Extension:RPED/RPED body.php

From MediaWiki.org
Jump to: navigation, search

RPED_body.php[edit | edit source]

<?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;
	}
}