User:Leucosticte/IWSandbox

hooks
 * @copyright GPL

class InterwikiExistenceHooks { public static function InterwikiExistenceCreateTable( $updater = null ) { if ( $updater === null ) { global $wgExtNewTables; $wgExtNewTables[] = array(				'iwe_page',				dirname( __FILE__ ) . '/iwetable.sql'			); } else { $updater->addExtensionUpdate( array( 'addTable', 'iwe_page', dirname( __FILE__ ). '/iwetable.sql', true ) ); }		return true; }

public static function interwikiExistenceLinkEnd( $dummy, Title $target, array $options,		&$html, array &$attribs, &$ret ) { global $wgInterwikiExistencePrefix, $wgInterwikiExistenceIwUrl, $wgInterwikiExistenceRecursionInProgress, $wgInterwikiExistenceLocalLinksGoInterwiki; $dbr = wfGetDB( DB_MASTER ); $title = $target->getFullText; $isInterwiki = false; $encodedTitle = $dbr->strencode ( $title ); #$encodedTitle = $title; if ( !$wgInterwikiExistenceRecursionInProgress && $target->getInterwiki 			== $wgInterwikiExistencePrefix ) { #$encodedTitle = $dbr->strencode ( substr ( $title, strlen (			$encodedTitle = substr ( $title, strlen (				$wgInterwikiExistencePrefix ) + 1, strlen ( $title ) #- $wgInterwikiExistencePrefix ) ); - $wgInterwikiExistencePrefix );			$isInterwiki = true;		}		$wgInterwikiExistenceRecursionInProgress = false;		$result = $dbr->selectRow ( 'iwe_page', array ( 'iwe_page_created',			'iwe_page_deleted' ), array (				'iwe_page_title' => $encodedTitle ) );		if ( $result ) {			if ( $result->iwe_page_created > $result->iwe_page_deleted && ( $isInterwiki || $wgInterwikiExistenceLocalLinksGoInterwiki ) ) {				$wgInterwikiExistenceRecursionInProgress = true;				if ( !$html ) {					$html = $title;				}				$ret = Linker::link ( Title::newFromText( $wgInterwikiExistencePrefix . ':'					. $encodedTitle ), $html );				return false;				}		}		if ( $isInterwiki ) {			$interwiki = Interwiki::fetch ( $wgInterwikiExistencePrefix );			$ret = Html::rawElement ( 'a', array ( 'href' => $interwiki->getURL ( $encodedTitle ), 'class' => 'new' ), #$title ), 'class' => 'new' ), $title );			return false;		}		return true;	}

public static function interwikiExistenceOnArticleSaveComplete ( &$article, &$user, $text,		$summary, $minoredit, $watchthis, $sectionanchor, &$flags, $revision, &$status, $baseRevId ) { global $wgInterwikiExistenceSeconds, $wgInterwikiExistenceNewOdds, $wgInterwikiExistenceDeleteOdds, $wgInterwikiExistenceRemoteWikiUrl, $wgInterwikiExistenceApiNewArgs, $wgInterwikiExistenceApiDeleteArgs, $wgInterwikiExistenceUserAgent, $wgInterwikiExistenceMinimumSeconds, $wgContLang, $wgVersion; // Do recentchanges API pull to check for new pages InterwikiExistenceHooks::interwikiExistenceUpdate ( INTERWIKIEXISTENCE_ROLLDICE			| INTERWIKIEXISTENCE_CHECKMINIMUMTIME,			$wgInterwikiExistenceNewOdds,			'interwikiexistencenewtimestamp', 'interwikiexistencenewconttimestamp',			true, $wgInterwikiExistenceRemoteWikiUrl, $wgInterwikiExistenceApiNewArgs,			'recentchanges', 'iwe_page_created', 'rccontinue',			$wgInterwikiExistenceSeconds, $wgInterwikiExistenceMinimumSeconds,			$wgInterwikiExistenceUserAgent ); // Do logevents API pull to check for deletions/restorations InterwikiExistenceHooks::interwikiExistenceUpdate ( INTERWIKIEXISTENCE_ROLLDICE			| INTERWIKIEXISTENCE_CHECKMINIMUMTIME,			$wgInterwikiExistenceDeleteOdds,			'interwikiexistencedeletetimestamp',			'interwikiexistencedeleteconttimestamp',			$wgInterwikiExistenceRemoteWikiUrl, $wgInterwikiExistenceApiDeleteArgs,			'logevents', 'iwe_page_created', 'lecontinue',			$wgInterwikiExistenceSeconds, $wgInterwikiExistenceMinimumSeconds,			$wgInterwikiExistenceUserAgent, 'restore', 'delete', 'iwe_page_deleted' ); return true; }

/**	 * @param $flags Integer bitfield: * 	INTERWIKIEXISTENCE_ROLLDICE * 		Roll dice to see if it's time to do the update * 	INTERWIKIEXISTENCE_CHECKMINIMUMTIME * 		Check whether it's been long enough since the last update * @param $odds * @param $lastRunProperty * @param $continueProperty * @param $continueProperty * @param $apiUrl * @param $apiArgs * @param $submodule * @param $iwepField * @param $continueType * @param $skipSeconds * @param $throttleSeconds * @param $userAgent * @param $createAction = null * @param $deleteAction = null * @param $addField = null * @param $deleteField = null */	public static function interwikiExistenceUpdate ( $flags, $odds, $lastRunProperty,		$continueProperty, $apiUrl, $apiArgs, $submodule, $iwepField,		$continueType, $skipSeconds, $throttleSeconds,		$userAgent, $createAction = null, $deleteAction = null, $addField = null,		$deleteField = null ) { $rollDice = $flags & INTERWIKIEXISTENCE_ROLLDICE; $checkMinimumTime = $flags & INTERWIKIEXISTENCE_CHECKMINIMUMTIME; // Roll the dice to decide whether to check whether it's time for an update.

if ( $rollDice ) { if ( rand ( 0, 360 ) > $odds ) { return INTERWIKIEXISTENCE_SKIPPED; }		}		$dbw = wfGetDB( DB_MASTER ); // Last-run timestamp stored in the user_properties table. $lastRunResult = $dbw->selectrow( 'user_properties', 'up_value', array ( 'up_user' => '1', 'up_property' => $lastRunProperty ) );		// QueryCont timestamp stored in the user_properties table. $continueResult = $dbw->selectrow( 'user_properties', 'up_value', array ( 'up_user' => '1', 'up_property' => $continueProperty ) );		// If no timestamp is in the table, abort; that indicates that update.php hasn't // been run yet. $timestamp = wfTimestampNow; if ( !$lastRunResult || !$continueResult ) { return INTERWIKIEXISTENCE_NOTIMESTAMP; } else { // If it hasn't been a long enough time, don't do the update yet. if ( $rollDice && $timestamp - $lastRunResult->up_value				< $skipSeconds ) { return INTERWIKIEXISTENCE_SKIPPED; }			if ( $checkMinimumTime && $timestamp - $lastRunResult->up_value				< $throttleSeconds ) { return INTERWIKIEXISTENCE_THROTTLED; }		}		// Poll $apiUrl = str_replace ( '$1', $continueResult->up_value, $apiUrl . $apiArgs ); $apiPull = InterwikiExistenceHooks::InterwikiExistenceApiPull ( $apiUrl,			$userAgent ); // No data? Bad data? if ( isset ( $apiPull['status'] ) ) { return $apiPull; }		// See what titles are in the database $firstElement = true; $cond = ''; $titles = array; foreach ( $apiPull['query'][$submodule] as $apiPullElement ) { $cleanTitle = $dbw->strencode ( $apiPullElement['title'] ); if ( !$firstElement ) { $cond .= " OR "; }                       $cond .= "iwe_page_title=". $dbw->addquotes ( $cleanTitle ); $firstElement = false; $titles[$cleanTitle] = InterwikiExistenceHooks::removeUndesirables (				$apiPullElement['timestamp'] ); $lastTimestamp = $titles[$cleanTitle]; }		$result = $dbw->select( 'iwe_page', array ( 'iwe_page_title', $iwepField ),			$cond ); if ( $result ) { foreach ( $result as $row ) { $timestamp = $titles[$row->iwe_page_title]; unset ( $titles[ $row->iwe_page_title ] ); if ( $iwepField = 'iwe_page_created' ) { $compare = $row->iwe_page_created; } else { $compare = $row->iwe_page_deleted; }				if ( $timestamp > $compare ) { $dbw->update ( 'iwe_page', array ( $iwepField => $timestamp ),						array ( 'iwe_page_title' => $row->iwe_page_title, "$timestamp > $iwepField" )					); }			}		}		// Insert rows $insertArray = array; foreach ( $titles as $title => $timestamp ) { if ( $title != 'updated' ) { $insertArray[] = array (					'iwe_page_title' => $title,					$iwepField => $timestamp				); }		}		$dbw->insert( 'iwe_page', $insertArray );

// Update lastrun timestamp if we've reached the end of the queries if ( !isset ( $apiPull['query-continue'] ) ) { $upsert = array (				'up_user' => '1',				'up_property' => $lastRunProperty,				'up_value' => InterwikiExistenceHooks::removeUndesirables					( $timestamp )			); $dbw->upsert(				'user_properties',				$upsert,				array ( 'up_user', 'up_property' ),				$upsert			); $timestamp = $lastTimestamp; $status = true; } else { $timestamp = InterwikiExistenceHooks::removeUndesirables (				$apiPull['query-continue'][$continueType] ); $status = INTERWIKIEXISTENCE_CONTINUING; }		// Either way, update the continue timestamp $upsert = array (				'up_user' => '1',				'up_property' => $continueProperty,				'up_value' => $timestamp			); $dbw->upsert(			'user_properties', $upsert, array ( 'up_user', 'up_property' ),			$upsert ); return $status; }

public static function interwikiExistenceApiPull ( $url, $userAgent ) { // Set up file_get_contents options $opts = array(			'http'=>array( 'method' => "GET", 'header' => $userAgent )		);		$streamContext = stream_context_create( $opts ); // Do the API pull $contents = file_get_contents ( $url, false, $streamContext ); if ( !$contents ) { wfDebugLog( 'InterwikiExistence', "Retrieval from $url failed\n" ); return array ( 'url' => $url, 'status' =>				INTERWIKIEXISTENCE_NORETRIEVE ); // Abort update }		// Decode and return API contents $apiPull = json_decode ( $contents, true ); if ( !$apiPull ) { wfDebugLog( 'InterwikiExistence', "json decode of $url failed\n" ); return array ( 'url' => $url, 'status' =>				INTERWIKIEXISTENCE_NODECODE ); // Abort update }		return $apiPull; }

public static function removeUndesirables ( $timestamp ) { return str_replace ( array ( '-', ':', 'T', 'Z' ), '', $timestamp ); } }

populate
 * @copyright GPL

require_once( dirname( __FILE__ ) . "/../../maintenance/Maintenance.php" );

class PopulateInterwikiExistencePageTable extends Maintenance { public function execute { global $wgInterwikiExistenceRemoteWikiUrl, $wgInterwikiExistenceApiAllPagesArgs, $wgInterwikiExistenceUserAgent; require_once 'setInterwikiExistenceTimestamp.php'; SetInterwikiExistenceTimestamp::setTimestamp ( 'new', 'now' ); SetInterwikiExistenceTimestamp::setTimestamp ( 'delete', 'now' ); InterwikiExistenceHooks::interwikiExistenceUpdate ( INTERWIKIEXISTENCE_CHECKMINIMUMSECONDS,		'interwikiexistencedeletetimestamp',			'interwikiexistencedeleteconttimestamp',			true, $wgInterwikiExistenceRemoteWikiUrl, $wgInterwikiExistenceApiDeleteArgs,			'logevents', 'iwe_page_deleted', 'lecontinue',			$wgInterwikiExistenceSeconds, $wgInterwikiExistenceMinimumSeconds,			$wgInterwikiExistenceUserAgent );

$dbw = wfGetDB( DB_MASTER ); $result = $dbw->selectrow( 'user_properties', 'up_value', array ( 'up_user' => '1', 'up_property' => 'interwikiexistenceallpagescont', ) );       if ( $result ) { $apiStart = $result->up_value; if ( !$apiStart ) { $apiStart = '!'; }       } else { $apiStart = '!'; }       echo "Starting with $apiStart ...\n"; while ( $apiStart != null ) { $apiUrl = $wgInterwikiExistenceRemoteWikiUrl. str_replace (               '$1', $apiStart, $wgInterwikiExistenceApiAllPagesArgs ); $apiPull = InterwikiExistenceHooks::InterwikiExistenceApiPull ( $apiUrl,               $wgInterwikiExistenceUserAgent ); if ( isset ( $apiPull['status'] ) ) { echo "There was a problem polling the API. URL = $apiUrl\n"; die; }           // See what titles are in the database $firstElement = true; $cond = ''; $titles = array; foreach ( $apiPull['query']['allpages'] as $apiPullElement ) { $cleanTitle = $dbw->strencode ( $apiPullElement['title'] ); if ( !$firstElement ) { $cond .= " OR "; }                           $cond .= "iwe_page_title=". $dbw->addquotes ( $cleanTitle ); $firstElement = false; $titles[$cleanTitle] = wfTimestampNow; }                   $result = $dbw->select( 'iwe_page', array ( 'iwe_page_title', 'iwe_page_created' ),                            $cond ); if ( $result ) { foreach ( $result as $row ) { $timestamp = $titles[$row->iwe_page_title]; unset ( $titles[ $row->iwe_page_title ] ); if ( $timestamp > $row->iwe_page_created ) { $dbw->update ( 'iwe_page', array ( 'iwe_page_created' => $timestamp ),                                               array ( 'iwe_page_title' => $row->iwe_page_title )                                        ); }                           }                    }                    // Insert rows $insertArray = array; foreach ( $titles as $title => $timestamp ) { if ( $title != 'updated' ) { $insertArray[] = array (                                           'iwe_page_title' => $title,                                            'iwe_page_created' => $timestamp                                    ); }                   }                    $dbw->insert( 'iwe_page', $insertArray ); // Update interwikiexistenceallpagescont timestamp if we've reached the end of the queries if ( !isset ( $apiPull['query-continue'] ) ) { echo "Population complete!\n"; $apiStart = null; } else { $apiStart = $apiPull['query-continue']['allpages']['apcontinue']; $upsert = array (                                   'up_user' => '1',                                    'up_property' => 'interwikiexistenceallpagescont',                                    'up_value' => $apiStart                            ); $dbw->upsert(                                   'user_properties',                                    $upsert,                                    array ( 'up_user', 'up_property' ),                                    $upsert                            ); echo "Continuing with $apiStart ...\n"; }       }    } }

$maintClass = 'PopulateInterwikiExistencePageTable'; if( defined('RUN_MAINTENANCE_IF_MAIN') ) { require_once( RUN_MAINTENANCE_IF_MAIN ); } else { require_once( DO_MAINTENANCE ); # Make this work on versions before 1.17 }

special
 * @copyright GPL

if ( !defined( 'MEDIAWIKI' ) ) { die( 'This file is a MediaWiki extension. It is not a valid entry point' ); }

class SpecialInterwikiExistence extends SpecialPage { function __construct { parent::__construct( 'InterwikiExistence', 'interwikiexistence' ); }

public function userCanExecute( User $user ) { return true; }

function execute( $par ) { global $wgInterwikiExistenceNewSeconds, $wgInterwikiExistenceDeleteSeconds, $wgInterwikiExistenceNewOdds, $wgInterwikiExistenceDeleteOdds, $wgInterwikiExistenceRemoteWikiUrl, $wgInterwikiExistenceApiNewArgs, $wgInterwikiExistenceApiDeleteArgs, $wgInterwikiExistenceUserAgent, $wgInterwikiExistenceMinimumNewSeconds, $wgInterwikiExistenceMinimumDeleteSeconds; $user = $this->getUser; if ( !$user->isAllowed( 'interwikiexistence' ) ) { throw new PermissionsError( null, array( array(                               'interwikiexistence-notallowed' ) ) ); }		$this->setHeaders; $output = $this->getOutput; $context = $this->getContext; $isNotExempt = !$user->isAllowed( 'interwikiexistencenoratelimit' ); // Don't roll dice or check time SpecialInterwikiExistence::reaction (			InterwikiExistenceHooks::interwikiExistenceUpdate ( INTERWIKIEXISTENCE_ROLLDICE | INTERWIKIEXISTENCE_CHECKMINIMUMTIME, $wgInterwikiExistenceNewOdds, 'interwikiexistencenewtimestamp', 'interwikiexistencenewconttimestamp', $wgInterwikiExistenceRemoteWikiUrl, $wgInterwikiExistenceApiNewArgs, 'recentchanges', 'iwe_page_created', 'rccontinue', $wgInterwikiExistenceNewSeconds, $wgInterwikiExistenceMinimumNewSeconds, $wgInterwikiExistenceUserAgent ), $output,				'interwikiexistence-creation',				$wgInterwikiExistenceMinimumNewSeconds ); SpecialInterwikiExistence::reaction (			InterwikiExistenceHooks::interwikiExistenceUpdate ( INTERWIKIEXISTENCE_ROLLDICE | INTERWIKIEXISTENCE_CHECKMINIMUMTIME, $wgInterwikiExistenceDeleteOdds, 'interwikiexistencedeletetimestamp', 'interwikiexistencedeleteconttimestamp', false, $wgInterwikiExistenceRemoteWikiUrl, $wgInterwikiExistenceApiDeleteArgs, 'logevents', 'iwe_page_deleted', 'lecontinue', $wgInterwikiExistenceDeleteSeconds, $wgInterwikiExistenceMinimumDeleteSeconds, true, $wgInterwikiExistenceUserAgent ), $output,				'interwikiexistence-deletion',				$wgInterwikiExistenceMinimumDeleteSeconds ); }

public static function reaction ( $input, $output, $action, $seconds ) { if ( is_array ( $input ) ) { if ( $input['status'] == INTERWIKIEXISTENCE_NORETRIEVE ) { $output->addWikiMsg ( 'interwikiexistence-trigger-noretrieve',                                       $result['url']); }                       if ( $input['status'] == INTERWIKIEXISTENCE_NODECODE ) { $output->addWikiMsg ( 'interwikiexistence-trigger-nodecode',                                       $result['url'] ); }               } else switch ( $input ) { case INTERWIKIEXISTENCE_SUCCESS: $output->addWikiMsg ( 'interwikiexistence-trigger-success',					wfMessage ( $action ) ); break; case INTERWIKIEXISTENCE_CONTINUING: $output->addWikiMsg ( 'interwikiexistence-trigger-continuing',					wfMessage ( $action ) ); break; case INTERWIKIEXISTENCE_THROTTLED: $output->addWikiMsg ( 'interwikiexistence-trigger-throttled',					$seconds, wfMessage ( $action ) ); break; case INTERWIKIEXISTENCE_NOTIMESTAMP: $output->addWikiMsg ( 'interwikiexistence-trigger-notimestamp',					wfMessage ( $action ) ); break; }		return; } }