('bovender')
 *
 *      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.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */
namespace LinkTitles;
/// @defgroup batch Batch processing
/// @cond
if ( !defined( 'MEDIAWIKI' ) ) {
	die( 'Not an entry point.' );
}
/// @endcond
 
/// Provides a special page that can be used to batch-process all pages in 
/// the wiki. By default, this can only be performed by sysops.
/// @ingroup batch
class Special extends \SpecialPage {
	/// Constructor. Announces the special page title and required user right 
	/// to the parent constructor.
	function __construct() {
		// the second parameter in the following function call ensures that only 
		// users who have the 'linktitles-batch' right get to see this page (by 
		// default, this are all sysop users).
		parent::__construct( 'LinkTitles', 'linktitles-batch' );
	}
	function getGroupName() {
		return 'pagetools';
	}
	/// Entry function of the special page class. Will abort if the user does 
	/// not have appropriate permissions ('linktitles-batch').
	/// @return undefined
	function execute($par) {
		// Prevent non-authorized users from executing the batch processing.
		if ( !$this->userCanExecute( $this->getUser() ) ) {
			$this->displayRestrictionError();
			return;
		}
		$request = $this->getRequest();
		$output = $this->getOutput();
		$this->setHeaders();
		// Determine whether this page was requested via GET or POST.
		// If GET, display information and a button to start linking.
		// If POST, start or continue the linking process.
		if ( $request->wasPosted() ) {
			if ( array_key_exists( 's', $request->getValues() ) ) {
				$this->process( $request, $output );
			}
			else
			{
				$this->buildInfoPage( $request, $output );
			}
		}
		else
		{
			$this->buildInfoPage( $request, $output );
		}
	}
	/// Processes wiki articles, starting at the page indicated by 
	/// $startTitle. If $wgLinkTitlesTimeLimit is reached before all pages are 
	/// processed, returns the title of the next page that needs processing.
	/// @param WebRequest $request WebRequest object that is associated with the special 
	///                            page.
	/// @param OutputPage $output  Output page for the special page.
	private function process( \WebRequest &$request, \OutputPage &$output) {
		global $wgLinkTitlesTimeLimit;
		// Start the stopwatch
		$startTime = microtime(true);
		// Connect to the database
		$dbr = wfGetDB( DB_SLAVE );
		// Fetch the start index and max number of records from the POST 
		// request.
		$postValues = $request->getValues();
		// Convert the start index to an integer; this helps preventing
		// SQL injection attacks via forged POST requests.
		$start = intval($postValues['s']);
		// If an end index was given, we don't need to query the database
		if ( array_key_exists('e', $postValues) ) {
			$end = intval($postValues['e']);
		}
		else 
		{
			// No end index was given. Therefore, count pages now.
			$end = $this->countPages($dbr);
		};
		array_key_exists('r', $postValues) ?
				$reloads = $postValues['r'] :
				$reloads = 0;
		// Retrieve page names from the database.
		$res = $dbr->select( 
			'page',
			'page_title', 
			array( 
				'page_namespace = 0', 
			), 
			__METHOD__, 
			array(
		 		'LIMIT' => 999999999,
				'OFFSET' => $start
			)
		);
		// Iterate through the pages; break if a time limit is exceeded.
		foreach ( $res as $row ) {
			$curTitle = $row->page_title;
			Extension::processPage( $curTitle, $this->getContext() );
			$start += 1;
			
			// Check if the time limit is exceeded
			if ( microtime(true)-$startTime > $wgLinkTitlesTimeLimit )
			{
				break;
			}
		}
		$this->addProgressInfo($output, $curTitle, $start, $end);
		// If we have not reached the last page yet, produce code to reload
		// the extension's special page.
		if ( $start < $end )
	 	{
			$reloads += 1;
			// Build a form with hidden values and output JavaScript code that 
			// immediately submits the form in order to continue the process.
			$output->addHTML($this->getReloaderForm($request->getRequestURL(), 
				$start, $end, $reloads));
		}
		else // Last page has been processed
		{
			$this->addCompletedInfo($output, $start, $end, $reloads);
		}
	}
	/// Adds WikiText to the output containing information about the extension 
	/// and a form and button to start linking.
	private function buildInfoPage( &$request, &$output ) {
		$url = $request->getRequestURL();
		// TODO: Put the page contents in messages in the i18n file.
		$output->addWikiText(
<<