Extension:RPED/RPED body.php

From MediaWiki.org
Jump to: navigation, search

RPED_body.php [edit]

<?php
 
/**
 * Remote Page Existence Detection (RPED) extension by Tisane
 * URL: http://www.mediawiki.org/wiki/Extension:RemotePageExistenceDetection
 *
 * This program is free software. You can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. You can also redistribute it and/or
 * modify it under the terms of the Creative Commons Attribution 3.0 license.
 *
 * This extension provides the Special Page used to import data into the page title table.
 *
 * Two tables are used - a control table and a page title table. The page title table consists of the
 * primary key and the page titles that are read from the file. If it takes more than 40 seconds to
 * read the file, then the page saves the file pointer to the control table and reloads the page, so
 * it can continue reading from the file. That one field is the only thing in the control table. If
 * you have a large page title file, it will take several minutes to read it. You can tweak the
 * $sleepNumber, $sleepTime and $secondsBeforeReload as needed to get the performance necessary. If
 * there is a malfunction in mid-upload, you may need to manually drop the control table. Bear in
 * mind this special page is open to all users. If it strips too many characters off the end of the
 * rows in our input file, then adjust $stripThisManyCharactersFromEnd.
 */
 
class RPED extends SpecialPage {
        function __construct() {
                parent::__construct( 'RPED' );
                wfLoadExtensionMessages('RPED');
                SpecialPage::SpecialPage( 'RPED' );
        }
 
 
        function execute( $par ) {
                require( "extensions/RPED/RPEDConfig.php" );
                global $wgRequest, $wgOut,$wgUser,$wgServer,$wgScriptPath;
 
                $displayMainMenu=true;
                if (!$this->userCanExecute( $wgUser )) {
                        $this->displayRestrictionError();
                        return;
                }
 
                if (!$wgUser->isAllowed( 'RPED' ) ){
                        $this->displayRestrictionError();
                        return;
                }
 
        // Initialize variables
        $sleepNumber=1000; /* Go to sleep every x records read from the file (to give the server a rest
                from queries)*/
        $sleepTime=1; // Go to sleep for x seconds
        $stripThisManyCharactersFromEnd=2; /* Strip this many characters from the end of each row read
                from the file*/
        $secondsBeforeReload=40; // Reload the page after x seconds and keep reading from the file
        $this->setHeaders();
        # Get request data from parameters
        $param = $wgRequest->getText('param');
 
        // Initialize database
        $con = mysql_connect($yourHost,$yourUsername,$yourPassword); /* This will fail unless you have
                supplied the correct data*/
        if (!$con){
                die('Could not connect: ' . mysql_error());
        }
 
        // Create the page title database
        //$sql=$con->prepare("CREATE DATABASE ?");
        //$sql->bindParam(1, $RPED_page_title_db);
        //mysql_query($sql,$con);
 
        $sqlString=sprintf("CREATE DATABASE %s",
                mysql_real_escape_string($RPED_page_title_db));
        mysql_query($sqlString,$con);
        mysql_select_db($RPED_page_title_db, $con); // Select the page title database
        $this->createControlTable($con);
 
        // See what's in the control table
        $myQuery='SELECT * FROM control_table';
        $result=mysql_query($myQuery,$con); // Get the entire control table
        if($result){
                $matches=mysql_num_rows  ( $result  );
                if ($matches>0){ // If the control table isn't empty...
                        //$timingResult=mysql_fetch_field($result); // Get the first row
                        $result2=mysql_fetch_field($result); // Get the second row
                        $result3=(int)$result2; // Convert to an integer
                        if ($result3>0){
                                $this->readTheFile(
                                        $fpointer=$result3,
                                        $con=$con,
                                        $stripThisManyCharactersFromEnd=$stripThisManyCharactersFromEnd,
                                        $sleepNumber=$sleepNumber,
                                        $sleepTime=$sleepTime,
                                        $secondsBeforeReload=$secondsBeforeReload); // Read the file in from where we left off
                        }
                }
        }
 
        if (isset($_POST['yescleardatabase'])){ // If we've confirmed to clear the database...
                $sql="DROP TABLE page_titles";
                mysql_query($sql,$con);         // Drop the page title table
                $sql="DROP TABLE control_table";
                mysql_query($sql,$con);         // Drop the control table
                // Create a new page title table
                $this->createpagetitleTable($con);
        }
        elseif (isset($_POST['cleardatabase'])){ // If we've selected to clear the database...
        $outputText='
                Are you sure that you want to clear the database?<br />
                <form method="post"
                        action="'.$this->findCurrentUrl().'"
                <input type="button" onclick="this.form.submit()" name="yescleardatabase" value="Yes" />
                <input type="submit" name="nodontcleardatabase" value="No" /></form>';
                $wgOut->addHTML($outputText);
                $displayMainMenu=false;
        }
        elseif (isset($_POST['requestall'])){ // If we've selected data from the central server...
                $newPassword='';
                for ($count=0; $count<32; $count++){ // A 32-digit randomly-generated password
                        $newPassword.=rand(0,9);
                }
                $sql="DROP TABLE password_table";
                mysql_query($sql,$con);         // Drop the password table
                $sql = "CREATE TABLE password_table(
                        password text(256)
                        )";
                mysql_query($sql,$con);
                $sql=sprintf("INSERT INTO password_table (password) VALUES ('%s')",
                        mysql_real_escape_string($newPassword));
                mysql_query($sql,$con);
                $centralServerURL.=$wgServer.$wgScriptPath.'|'.$newPassword; // Give the Server the password
                $response=file_get_contents($centralServerURL);
                $wgOut->addWikiText($response);
        }
        elseif (isset($_POST['unsubscribe'])){ // If we've asked to unsubscribe...
                $newPassword='';
                for ($count=0; $count<32; $count++){ // A 32-digit randomly-generated password
                        $newPassword.=rand(0,9);
                }
                $sql="DROP TABLE password_table";
                mysql_query($sql,$con);         // Drop the password table
                $sql = "CREATE TABLE password_table(
                        password text(256)
                        )";
                mysql_query($sql,$con);
                $sql=sprintf("INSERT INTO password_table (password) VALUES ('%s')",
                        mysql_real_escape_string($newPassword));
                mysql_query($sql,$con);
                $centralServerURL.=$wgServer.$wgScriptPath.'|'.$newPassword.'|'."unsubscribe";
                $response=file_get_contents($centralServerURL);
                $wgOut->addWikiText($response);
        }
        elseif (isset($_POST['uploadfile'])){ // If we've selected to read from a file...
        // Create the page title table
        $this->createpagetitleTable($con); 
         $this->readTheFile( // Start at the beginning of the file
                $fpointer=0,
                $con=$con,
                $stripThisManyCharactersFromEnd=$stripThisManyCharactersFromEnd,
                $sleepNumber=$sleepNumber,$sleepTime=$sleepTime,
                $secondsBeforeReload=$secondsBeforeReload); // Read the file in from where we left off
        }
        elseif (isset($_POST['changepassword'])){
                $newPassword = $_POST["newPassword"];
                $confirmPassword = $_POST["confirmPassword"];
                if ($newPassword==''){
                        $outputText='<big>The new password cannot be blank.<br /><br /></big>';
                        $wgOut->addHTML($outputText);
                }
                elseif ($newPassword!=$confirmPassword){
                        $outputText='<big>The new password and confirm password did not match.<br /><br /></big>';
                        $wgOut->addHTML($outputText);
                }
                else{
                        $sql="DROP TABLE password_table";
                        mysql_query($sql,$con);         // Drop the password table
                        $sql = "CREATE TABLE password_table(
                                password text(256)
                        )";
                        mysql_query($sql,$con);
                        $sql=sprintf("INSERT INTO password_table (password) VALUES ('%s')",
                                mysql_real_escape_string($newPassword));
                        mysql_query($sql,$con);
                        $outputText='<big>Password successfully changed!<br /><br /></big>';
                        $wgOut->addHTML($outputText);
                }
        }
 
        // ************** Main menu ***********
        if ($displayMainMenu==true){
 
                // $outputText='
                        // <b>Change password:</b><br />
                        // <form method="post"
                                // action="'.$this->findCurrentUrl().'"
                                // enctype="multipart/form-data">
                        // New password: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="text" name="newPassword"><br />
                        // Confirm password: <input type="text" name="confirmPassword"><br />
                        // <input type="submit" name="changepassword" value="Change password" />
                        // <input type="submit" name="cleardatabase" value="Clear database" />
                        // <input type="submit" name="requestall"
                                // value="Start subscription and request new page title data from central server" />
                        // <input type="submit" name="unsubscribe"
                                // value="Unsubscribe to page title data syndication" />
                        // <br /><b>Upload page title file:</b><br />
                        // <label for="file">Filename:</label><input type="file" name="file" id="file" /><br />
                        // <input type="submit" name="uploadfile" value="Upload file" />
                        // </form>';
                        $outputText='It is not recommended that you push these buttons unless you know what you
                        are doing.<br />
                        <form method="post"
                                action="'.$this->findCurrentUrl().'"
                                enctype="multipart/form-data">
                        <input type="submit" name="cleardatabase" value="Clear database" />
                        <input type="submit" name="requestall"
                                value="Start subscription and request new page title data from central server" />
                        <input type="submit" name="unsubscribe"
                                value="Unsubscribe to page title data syndication" />
                        </form>';
                $wgOut->addHTML($outputText);
                }
        }
 
        function createpagetitleTable($con) // Create the page title table
        {
        $sql = "CREATE TABLE page_titles(
                p_ID int NOT NULL AUTO_INCREMENT,
                PRIMARY KEY(p_ID),
                page_title text(256)
        )";
        mysql_query($sql,$con);
        $sql="CREATE INDEX pageind on page_titles (page_title)";
        mysql_query($sql,$con);
        }
 
        function createControlTable($con){
                global $wgOut;
                // Create the control table, which will have only one column
                $sql = "CREATE TABLE control_table(
                        offset_number text(256)
                )";
                mysql_query($sql,$con);
        }       
 
        function readTheFile($fpointer,$con,$stripThisManyCharactersFromEnd,$sleepNumber,$sleepTime,
                $secondsBeforeReload){
                global $wgOut;
                $startTime=time(); // Initial time; 40 seconds later, we will reload the page.
                //$wgOut->addWikiText('Reading file...');
                //ini_set  ( 'max_execution_time'  , 300  ); // No need for this
                // This will fail unless you have created an "upload" folder in your mediawiki folder.
                move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);
                $file=fopen("upload/" . $_FILES["file"]["name"],"r");
                if ($fpointer>0){
                   fseek($file,$fpointer); // Go to the offset point in the file
                }
                while(!feof($file)){ // Go until the end of the file
                        $myFgets=fgets($file); // Get the next line from the file
                        if (substr($myFgets  , strlen($myFgets) - 2  ,2  )=='\n'){ // If it ends in a newline...
                                $myFgets=substr  ( $myFgets  , 0  ,strlen($myFgets) - 2  ); // Strip the newline off -2
                        }
                        if (substr($myFgets  , strlen($myFgets) - 1  ,1  )=='\n'){ // If it ends in a newline...
                                $myFgets=substr  ( $myFgets  , 0  ,strlen($myFgets) - 1  ); // Strip the newline off -1
                        }
                        while (substr($myFgets  , strlen($myFgets) - 1  ,1  )==' '){ // If it ends in a space...
                                $myFgets=substr  ( $myFgets  , 0  ,strlen($myFgets) - 1  ); // Strip the space
                        }
                        // Strip the last characters
                        $myFgets=substr  ( $myFgets  , 0  ,strlen($myFgets) - $stripThisManyCharactersFromEnd  );
 
                        // Is this newline messing us up?
 
                        $filesql=$con->prepare("INSERT INTO page_titles (page_title) VALUES ('?')");
                        $filesql->bindParam(1, $myFgets);
                        /*if ($count2>100) // Send a query every this often
                        {
                                mysql_query($filesql,$con); // Save page title to the database
                                $filesql='';
                                $count2=0;
                                }
                                $count2++; */
                        $count++;
                        if ($count>$sleepNumber) // Give it some time to catch up!
                        {
                                sleep($sleepTime);
                                $count=0;
                        }
                        $filesql->execute(); // Save what remains in the buffer
                        if (time()-$startTime>$secondsBeforeReload){ // At 40 seconds, reload!  
                                $sql="DELETE FROM control_table";
                                mysql_query($sql,$con); // Clear the control table
                                $fpointer=ftell($file); // Find the current offset in the file
                                // Query to save the fpointer to the control table
                                $sql=sprintf("INSERT INTO control_table (offset_number) VALUES ('%s')",
                                        mysql_real_escape_string($fpointer));
                                //$wgOut->addWikiText($sql);
                                mysql_query($sql,$con); // Execute query to save the fpointer to the control table
                                // Figure out our current URL and go there again
                                $pageURL = 'Location: '.$this->findCurrentUrl();
                                header($pageURL); // Reload this page
                        }
                }
                //mysql_query($filesql,$con); // Save page title to the database
                $sql="DROP TABLE control_table";
                mysql_query($sql,$con);         // Drop the control table
                fclose($file); 
                $wgOut->addWikiText("File successfully uploaded!<br />");
                /*
                $handle = fopen("upload/" . $_FILES["file"]["name"],"r");
                $count=0;
                $arraycount=0;
                while ($userinfo = fscanf($handle, "%s\n")) {
                        if ($count>1000){
                                mysql_query($filesql[$arraycount],$con);
                                $arraycount++;
                                $count=0;
                        }
                        list ($name) = $userinfo;
                        $filesql[arraycount].= "INSERT INTO page_titles (page_title) VALUES ('".$name."\n')";
                        $wgOut->addWikiText($filesql[arraycount]);
                        $count++;
                }
                // $wgOut->addWikiText($filesql[$arraycount]);
                mysql_query($filesql[$arraycount],$con);*/
                mysql_close($con);
        }
 
        Function findCurrentUrl()
        {
                // Figure out our current URL and go there again
                $pageURL = 'http';
                if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on"){
                        $pageURL .= "s";
                }
                $pageURL .= "://";
                if ($_SERVER["SERVER_PORT"] != "80") {
                        $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
                } else {
                        $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
                }
                return $pageURL;
        }
}