('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. */ if ( !defined( 'MEDIAWIKI' ) ) { die( 'Not an entry point.' ); } /// 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. class SpecialLinkTitles extends SpecialPage { 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'); } /// Entry function of the special page class. Will abort if the user does /// not have appropriate permissions ('linktitles-batch'). 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. private function process(&$request, &$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( 'OFFSET' => $start, 'LIMIT' => '1' ) ); // Iterate through the pages; break if a time limit is exceeded. foreach ( $res as $row ) { $curTitle = $row->page_title; LinkTitles::processPage($curTitle, $this->getContext()); $start += 1; // Check if the time limit is exceeded if ( microtime(true)-$startTime > $wgLinkTitlesTimeLimit ) { $reloads += 1; 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 ) { // 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( <<addHTML( << EOF ); } /// Produces informative output in WikiText format to show while working. private function addProgressInfo(&$output, $curTitle, $start, $end) { $progress = $start / $end * 100; $percent = sprintf("%01.1f", $progress); $output->addWikiText( <<addHTML( <<Page ${start} of ${end}.

${percent}%
EOF ); $output->addWikiText( << EOF ; } /// Adds statistics to the page when all processing is done. private function addCompletedInfo(&$output, $start, $end, $reloads) { global $wgLinkTitlesTimeLimit; $pagesPerReload = sprintf('%0.1f', $end / $reloads); $output->addWikiText( <<select( 'page', 'page_id', array( 'page_namespace = 0', ), __METHOD__ ); return $res->numRows(); } } // vim: ts=2:sw=2:noet