http://www.mediawiki.org/wiki/Special:Code/MediaWiki/68114
Revision: 68114 Author: tisane Date: 2010-06-16 02:41:13 +0000 (Wed, 16 Jun 2010) Log Message: ----------- Add integration_recentchanges and integration_watchlist tables; Special:InterwikiWatchlist and Special:InterwikiRecentChanges are excluded from this commit because they don't work yet Modified Paths: -------------- trunk/extensions/InterwikiIntegration/InterwikiIntegration.hooks.php trunk/extensions/InterwikiIntegration/InterwikiIntegration.php trunk/extensions/InterwikiIntegration/SpecialInterwikiIntegration.php Added Paths: ----------- trunk/extensions/InterwikiIntegration/interwikiintegration-recentchanges.sql trunk/extensions/InterwikiIntegration/interwikiintegration-watchlist.sql Modified: trunk/extensions/InterwikiIntegration/InterwikiIntegration.hooks.php =================================================================== --- trunk/extensions/InterwikiIntegration/InterwikiIntegration.hooks.php 2010-06-16 01:30:14 UTC (rev 68113) +++ trunk/extensions/InterwikiIntegration/InterwikiIntegration.hooks.php 2010-06-16 02:41:13 UTC (rev 68114) @@ -1,8 +1,7 @@ <?php class InterwikiIntegrationHooks { - - /* + /** * Creates necessary tables */ public static function InterwikiIntegrationCreateTable() { @@ -19,10 +18,18 @@ 'integration_iwlinks', dirname( __FILE__ ) . '/interwikiintegration-iwlinks.sql' ); + $wgExtNewTables[] = array( + 'integration_watchlist', + dirname( __FILE__ ) . '/interwikiintegration-watchlist.sql' + ); + $wgExtNewTables[] = array( + 'integration_recentchanges', + dirname( __FILE__ ) . '/interwikiintegration-recentchanges.sql' + ); return true; } - /* + /** * Update the integration_iwlinks table when interwiki links are added or * removed from articles. */ @@ -111,7 +118,7 @@ return true; } - /* + /** * When a page is created, purge caches of pages that link to it interwiki */ public static function InterwikiIntegrationArticleInsertComplete ( &$article, &$user, $text, $summary, $minoredit, @@ -120,7 +127,7 @@ return true; } - /* + /** * When a page is deleted, purge caches of pages that link to it interwiki */ public static function InterwikiIntegrationArticleDeleteComplete( &$article, &$user, $reason, $id ) { @@ -133,7 +140,7 @@ return true; } - /* + /** * When a page is undeleted, purge caches of pages that link to it interwiki */ public static function InterwikiIntegrationArticleUndelete ( $title, $create ) { @@ -143,7 +150,7 @@ return true; } - /* + /** * When a page is moved, purge caches of pages that link to the new page interwiki */ public static function InterwikiIntegrationTitleMoveComplete ( &$title, &$newtitle, &$user, $oldid, $newid ) { @@ -151,7 +158,7 @@ return true; } - /* + /** * When a page is blanked, purge caches of pages that link to the new page interwiki. * This is called by a PureWikiDeletion hook. */ @@ -160,7 +167,7 @@ return true; } - /* + /** * When a page is unblanked, purge caches of pages that link to the new page interwiki. * This is called by a PureWikiDeletion hook. */ @@ -169,6 +176,10 @@ return true; } + /** + * Purges squids and invalidates caches of pages that link to $title + * interwiki. + */ public static function PurgeReferringPages ( $title ) { global $wgDBname, $wgInterwikiIntegrationPrefix; @@ -190,8 +201,7 @@ array ( 'integration_iwl_prefix' => $thisPrefix, 'integration_iwl_title' => $titleName - ), - __METHOD__ + ) ); if ( $result ) { $referringPage = $result->integration_iwl_from; @@ -213,7 +223,7 @@ return true; } - /* + /** * Determines whether an interwiki link to a wiki on the same wiki * farm is broken or not; if so, it will be colored red and link to the * edit page on the target wiki @@ -221,10 +231,8 @@ public static function InterwikiIntegrationLink( $skin, $target, &$text, &$customAttribs, &$query, &$options, &$ret ) { global $wgInterwikiIntegrationBrokenLinkStyle, $wgPureWikiDeletionInEffect; - if ( $target->isExternal() ) { $dbr = wfGetDB( DB_SLAVE ); - $interwikiPrefix = $target->getInterwiki (); $interwikiPrefix{0} = strtolower($interwikiPrefix{0}); $result = $dbr->selectRow( @@ -232,15 +240,11 @@ 'integration_dbname', array( "integration_prefix" => $interwikiPrefix ) ); - if ( !$result ) { return true; } - $targetDb = $result->integration_dbname; - $dbrTarget = wfGetDB( DB_SLAVE, array(), $targetDb ); - $title = $target->getDBkey (); $colonPos = strpos ( $title, ':' ); $namespaceIndex = ''; @@ -310,5 +314,95 @@ } return true; } -} - + + /** + * Flush old entries from the `integration_recentchanges` table; we do this on + * random requests so as to avoid an increase in writes for no good reason + */ + public static function InterwikiIntegrationArticleEditUpdatesDeleteFromRecentchanges( &$article ) { + if ( 0 == mt_rand( 0, 99 ) ) { + global $wgRCMaxAge; + $dbw = wfGetDB( DB_MASTER ); + $cutoff = $dbw->timestamp( time() - $wgRCMaxAge ); + $recentchanges = $dbw->tableName( 'integration_recentchanges' ); + $sql = "DELETE FROM $recentchanges WHERE integration_rc_timestamp < '{$cutoff}'"; + $dbw->query( $sql ); + } + return true; + } + + /** + * Save recent changes to integration_recentchanges + */ + public static function InterwikiIntegrationRecentChange_save( $recentChange ) { + $dbw = wfGetDB( DB_MASTER ); + global $wgDBname; + foreach ( $recentChange->mAttribs as $key => $value ) { + $newKey = "integration_" . $key; + $iRecentChange[$newKey] = $value; + } + $iRecentChange['integration_rc_db'] = $wgDBname; + $dbw->insert( 'integration_recentchanges', $iRecentChange ); + return true; + } + + /** + * Add newly watched articles to integration_watchlist + */ + public static function InterwikiIntegrationWatchArticleComplete( &$user, &$article ) { + $title = $article->getTitle(); + if ( $title->isTalkPage () ) { + $subjectNamespace = $title->getSubjectPage()->getNamespace(); + $talkNamespace = $title->getNamespace(); + } else { + $subjectNamespace = $title->getNamespace(); + $talkNamespace = $title->getTalkPage()->getNamespace(); + } + $DBkey = $title->getDBkey(); + $dbw = wfGetDB( DB_MASTER ); + $dbw->insert( 'integration_watchlist', + array( + 'integration_wl_user' => $user->id, + 'integration_wl_namespace' => $subjectNamespace, + 'integration_wl_title' => $DBkey, + 'integration_wl_notificationtimestamp' => null + ) ); + $dbw->insert( 'integration_watchlist', + array( + 'integration_wl_user' => $this->id, + 'integration_wl_namespace' => $talkNamespace, + 'integration_wl_title' => $DBkey, + 'integration_wl_notificationtimestamp' => null + ) ); + return true; + } + + /** + * Remove newly unwatched articles from integration_watchlist + */ + public static function InterwikiIntegrationUnwatchArticleComplete ( &$user, &$article ) { + $title = $article->getTitle(); + if ( $title->isTalkPage () ) { + $subjectNamespace = $title->getSubjectPage()->getNamespace(); + $talkNamespace = $title->getNamespace(); + } else { + $subjectNamespace = $title->getNamespace(); + $talkNamespace = $title->getTalkPage()->getNamespace(); + } + $DBkey = $title->getDBkey(); + $dbw = wfGetDB( DB_MASTER ); + $dbw->delete( 'integration_watchlist', + array( + 'integration_wl_user' => $user->id, + 'integration_wl_namespace' => $subjectNamespace, + 'integration_wl_title' => $DBkey + ) ); + $dbw->insert( 'integration_watchlist', + array( + 'integration_wl_user' => $this->id, + 'integration_wl_namespace' => $talkNamespace, + 'integration_wl_title' => $DBkey + ) ); + return true; + } +} \ No newline at end of file Modified: trunk/extensions/InterwikiIntegration/InterwikiIntegration.php =================================================================== --- trunk/extensions/InterwikiIntegration/InterwikiIntegration.php 2010-06-16 01:30:14 UTC (rev 68113) +++ trunk/extensions/InterwikiIntegration/InterwikiIntegration.php 2010-06-16 02:41:13 UTC (rev 68114) @@ -17,7 +17,6 @@ /* Alert the user that this is not a valid entry point to MediaWiki if they try to access the special pages file directly.*/ - if ( !defined( 'MEDIAWIKI' ) ) { echo <<<EOT To install the InterwikiIntegration extension, put the following line in LocalSettings.php: @@ -25,19 +24,21 @@ EOT; exit( 1 ); } - $wgExtensionCredits['other'][] = array( 'path' => __FILE__, 'name' => 'Interwiki Integration', 'author' => 'Tisane', 'url' => 'http://www.mediawiki.org/wiki/Extension:InterwikiIntegration', 'descriptionmsg' => 'interwikiintegration-desc', - 'version' => '1.0.3', + 'version' => '1.0.4', ); - $dir = dirname( __FILE__ ) . '/'; $wgAutoloadClasses['InterwikiIntegrationHooks'] = $dir . 'InterwikiIntegration.hooks.php'; $wgAutoloadClasses['PopulateInterwikiIntegrationTable'] = "$dir/SpecialInterwikiIntegration.php"; +$wgAutoloadClasses['PopulateInterwikiWatchlistTable'] = "$dir/SpecialInterwikiIntegration.php"; +$wgAutoloadClasses['PopulateInterwikiRecentChangesTable'] = "$dir/SpecialInterwikiIntegration.php"; +#$wgAutoloadClasses['InterwikiWatchlist'] = "$dir/SpecialInterwikiWatchlist.php"; +#$wgAutoloadClasses['InterwikiRecentChanges'] = "$dir/SpecialInterwikiRecentChanges.php"; $wgExtensionMessagesFiles['InterwikiIntegration'] = $dir . 'InterwikiIntegration.i18n.php'; $wgExtensionAliasesFiles['InterwikiIntegration'] = $dir . 'InterwikiIntegration.alias.php'; $wgHooks['LoadExtensionSchemaUpdates'][] = 'InterwikiIntegrationHooks::InterwikiIntegrationCreateTable'; @@ -49,12 +50,22 @@ $wgHooks['TitleMoveComplete'][] = 'InterwikiIntegrationHooks::InterwikiIntegrationTitleMoveComplete'; $wgHooks['PureWikiDeletionArticleBlankComplete'][] = 'InterwikiIntegrationHooks::InterwikiIntegrationArticleBlankComplete'; $wgHooks['PureWikiDeletionArticleUnblankComplete'][] = 'InterwikiIntegrationHooks::InterwikiIntegrationArticleUnblankComplete'; - -$wgSpecialPages['PopulateInterwikiIntegrationTable'] = 'PopulateInterwikiIntegrationTable'; +$wgHooks['ArticleEditUpdatesDeleteFromRecentchanges'][] = 'InterwikiIntegrationHooks::InterwikiIntegrationArticleEditUpdatesDeleteFromRecentchanges'; +$wgHooks['RecentChange_save'][] = 'InterwikiIntegrationHooks::InterwikiIntegrationRecentChange_save'; +$wgHooks['WatchArticleComplete'][] = 'InterwikiIntegrationHooks::InterwikiIntegrationWatchArticleComplete'; +$wgHooks['UnwatchArticleComplete'][] = 'InterwikiIntegrationHooks::InterwikiIntegrationUnwatchArticleComplete'; +$wgSpecialPages['PopulateInterwikiIntegrationTable'] = 'PopulateInterwikiIntegrationTable'; +$wgSpecialPages['PopulateInterwikiWatchlistTable'] = 'PopulateInterwikiWatchlistTable'; +$wgSpecialPages['PopulateInterwikiRecentChangesTable'] = 'PopulateInterwikiRecentChangesTable'; +#$wgSpecialPages['InterwikiWatchlist'] = 'InterwikiWatchlist'; +#$wgSpecialPages['InterwikiRecentChanges'] = 'InterwikiRecentChanges'; +$wgSpecialPageGroups['InterwikiWatchlist'] = 'changes'; +$wgSpecialPageGroups['InterwikiRecentChanges'] = 'changes'; $wgSharedTables[] = 'integration_prefix'; $wgSharedTables[] = 'integration_namespace'; $wgSharedTables[] = 'integration_iwlinks'; +$wgSharedTables[] = 'integration_watchlist'; +$wgSharedTables[] = 'integration_recentchanges'; $wgInterwikiIntegrationBrokenLinkStyle = "color: red"; - $wgAvailableRights[] = 'integration'; $wgGroupPermissions['bureaucrat']['integration'] = true; \ No newline at end of file Modified: trunk/extensions/InterwikiIntegration/SpecialInterwikiIntegration.php =================================================================== --- trunk/extensions/InterwikiIntegration/SpecialInterwikiIntegration.php 2010-06-16 01:30:14 UTC (rev 68113) +++ trunk/extensions/InterwikiIntegration/SpecialInterwikiIntegration.php 2010-06-16 02:41:13 UTC (rev 68114) @@ -1,7 +1,11 @@ <?php +/* + * A special page that populates the Integration tables, specifically + * integration_prefix and integration_namespace + */ class PopulateInterwikiIntegrationTable extends SpecialPage { function __construct() { - parent::__construct( 'PopulateInterwikiIntegrationTable','integration' ); + parent::__construct( 'PopulateInterwikiIntegrationTable', 'integration' ); wfLoadExtensionMessages( 'InterwikiIntegration' ); } @@ -17,12 +21,9 @@ } $dbr = wfGetDB( DB_SLAVE ); $dbw = wfGetDB( DB_MASTER ); - $localDBname = $dbr -> getProperty ( 'mDBname' ); - $dbw->delete ( 'integration_prefix', '*' ); if ( isset ( $wgInterwikiIntegrationPrefix ) ) { - foreach ( $wgInterwikiIntegrationPrefix as $thisPrefix => $thisDatabase ) { $thisPWD = 0; if ( isset ( $wgInterwikiIntegrationPWD[$thisDatabase]) @@ -34,12 +35,10 @@ 'integration_prefix' => $thisPrefix, 'integration_pwd' => $thisPWD ); - $dbw->insert ( 'integration_prefix', $newDatabaseRow ); - + $dbw->insert ( 'integration_prefix', $newDatabaseRow ); foreach ( $wgLocalDatabases as $thisDB ) { $foreignDbr = wfGetDB ( DB_SLAVE, array(), $thisDB ); $foreignDbw = wfGetDB ( DB_MASTER, array(), $thisDB ); - if ( $thisDB != $localDBname && $thisDatabase == $localDBname ) { $foreignResult = $foreignDbr->selectRow( 'interwiki', @@ -62,14 +61,11 @@ } } } - $myCache = new LocalisationCache ( $wgLocalisationCacheConf ); - $namespaceNames = $myCache->getItem ( $wgLanguageCode,'namespaceNames' ); $namespaceNames[NS_PROJECT] = $wgMetaNamespace; $namespaceNames[NS_PROJECT_TALK] = $wgMetaNamespace."_talk"; $dbw->delete ( 'integration_namespace', array( 'integration_dbname' => $localDBname ) ); - foreach ( $namespaceNames as $key => $thisName ) { $newNamespaceRow = array ( 'integration_dbname' => $localDBname, 'integration_namespace_index' => $key, @@ -104,3 +100,79 @@ return; } } + +/** + * A special page that populates the Interwiki watchlist table. + */ +class PopulateInterwikiWatchlistTable extends SpecialPage { + function __construct() { + parent::__construct( 'PopulateInterwikiWatchlistTable', 'integration' ); + wfLoadExtensionMessages( 'InterwikiIntegration' ); + } + + function execute( $par ) { + global $wgInterwikiIntegrationPrefix, $wgOut; + $dbr = wfGetDB( DB_SLAVE ); + $dbw = wfGetDB( DB_MASTER ); + $dbw->delete ( 'integration_watchlist', '*' ); + $dbList = array_unique ( $wgInterwikiIntegrationPrefix ); + foreach ( $dbList as $thisDb ) { + $thisDbr = wfGetDB( DB_SLAVE, array(), $thisDb ); + $watchlistRes = $thisDbr->select( + 'watchlist', + '*' + ); + if( $watchlistRes->numRows() > 0 ) { + while( $row = $watchlistRes->fetchObject() ) { + foreach ( $row as $key => $value ) { + $newKey = "integration_" . $key; + $iWatchlist[$newKey] = $value; + } + $iWatchlist['integration_wl_db'] = $thisDb; + $dbw->insert( 'integration_watchlist', $iWatchlist ); + } + } + } + $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) ); + $wgOut->addWikiMsg( 'interwikiwatchlist-setuptext' ); + return; + } +} + +/** + * A special page that populates the interwiki recent changes table. + */ +class PopulateInterwikiRecentChangesTable extends SpecialPage { + function __construct() { + parent::__construct( 'PopulateInterwikiRecentChangesTable', 'integration' ); + wfLoadExtensionMessages( 'InterwikiIntegration' ); + } + + function execute( $par ) { + global $wgInterwikiIntegrationPrefix, $wgOut; + $dbr = wfGetDB( DB_SLAVE ); + $dbw = wfGetDB( DB_MASTER ); + $dbw->delete ( 'integration_recentchanges', '*' ); + $dbList = array_unique ( $wgInterwikiIntegrationPrefix ); + foreach ( $dbList as $thisDb ) { + $thisDbr = wfGetDB( DB_SLAVE, array(), $thisDb ); + $recentchangesRes = $thisDbr->select( + 'recentchanges', + '*' + ); + if( $recentchangesRes->numRows() > 0 ) { + while( $row = $recentchangesRes->fetchObject() ) { + foreach ( $row as $key => $value ) { + $newKey = "integration_" . $key; + $iRecentChange[$newKey] = $value; + } + $iRecentChange['integration_rc_db'] = $thisDb; + $dbw->insert( 'integration_recentchanges', $iRecentChange ); + } + } + } + $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) ); + $wgOut->addWikiMsg( 'interwikirecentchanges-setuptext' ); + return; + } +} \ No newline at end of file Added: trunk/extensions/InterwikiIntegration/interwikiintegration-recentchanges.sql =================================================================== --- trunk/extensions/InterwikiIntegration/interwikiintegration-recentchanges.sql (rev 0) +++ trunk/extensions/InterwikiIntegration/interwikiintegration-recentchanges.sql 2010-06-16 02:41:13 UTC (rev 68114) @@ -0,0 +1,91 @@ +BEGIN; + +-- +-- Primarily a summary table for Special:Recentchanges, +-- this table contains some additional info on edits from +-- the last few days, see Article::editUpdates() +-- +CREATE TABLE /*_*/integration_recentchanges ( + integration_rc_global_id int NOT NULL PRIMARY KEY AUTO_INCREMENT, + + -- Local rc_id + integration_rc_id int NOT NULL, + + -- Database name of the wiki + integration_rc_db varchar(256) binary NOT NULL, + + integration_rc_timestamp varbinary(14) NOT NULL default '', + integration_rc_cur_time varbinary(14) NOT NULL default '', + + -- As in revision + integration_rc_user int unsigned NOT NULL default 0, + integration_rc_user_text varchar(255) binary NOT NULL, + + -- When pages are renamed, their RC entries do _not_ change. + integration_rc_namespace int NOT NULL default 0, + integration_rc_title varchar(255) binary NOT NULL default '', + + -- as in revision... + integration_rc_comment varchar(255) binary NOT NULL default '', + integration_rc_minor tinyint unsigned NOT NULL default 0, + + -- Edits by user accounts with the 'bot' rights key are + -- marked with a 1 here, and will be hidden from the + -- default view. + integration_rc_bot tinyint unsigned NOT NULL default 0, + + integration_rc_new tinyint unsigned NOT NULL default 0, + + -- Key to page_id (was cur_id prior to 1.5). + -- This will keep links working after moves while + -- retaining the at-the-time name in the changes list. + integration_rc_cur_id int unsigned NOT NULL default 0, + + -- rev_id of the given revision + integration_rc_this_oldid int unsigned NOT NULL default 0, + + -- rev_id of the prior revision, for generating diff links. + integration_rc_last_oldid int unsigned NOT NULL default 0, + + -- These may no longer be used, with the new move log. + integration_rc_type tinyint unsigned NOT NULL default 0, + integration_rc_moved_to_ns tinyint unsigned NOT NULL default 0, + integration_rc_moved_to_title varchar(255) binary NOT NULL default '', + + -- If the Recent Changes Patrol option is enabled, + -- users may mark edits as having been reviewed to + -- remove a warning flag on the RC list. + -- A value of 1 indicates the page has been reviewed. + integration_rc_patrolled tinyint unsigned NOT NULL default 0, + + -- Recorded IP address the edit was made from, if the + -- $wgPutIPinRC option is enabled. + integration_rc_ip varbinary(40) NOT NULL default '', + + -- Text length in characters before + -- and after the edit + integration_rc_old_len int, + integration_rc_new_len int, + + -- Visibility of recent changes items, bitfield + integration_rc_deleted tinyint unsigned NOT NULL default 0, + + -- Value corresonding to log_id, specific log entries + integration_rc_logid int unsigned NOT NULL default 0, + -- Store log type info here, or null + integration_rc_log_type varbinary(255) NULL default NULL, + -- Store log action or null + integration_rc_log_action varbinary(255) NULL default NULL, + -- Log params + integration_rc_params blob NULL +) /*$wgDBTableOptions*/; + +CREATE INDEX /*i*/integration_rc_timestamp ON integration_recentchanges (integration_rc_timestamp); +CREATE INDEX /*i*/integration_rc_namespace_title ON integration_recentchanges (integration_rc_namespace, integration_rc_title); +CREATE INDEX /*i*/integration_rc_cur_id ON integration_recentchanges (integration_rc_cur_id); +CREATE INDEX /*i*/integration_new_name_timestamp ON integration_recentchanges (integration_rc_new,integration_rc_namespace,integration_rc_timestamp); +CREATE INDEX /*i*/integration_rc_ip ON integration_recentchanges (integration_rc_ip); +CREATE INDEX /*i*/integration_rc_ns_usertext ON integration_recentchanges (integration_rc_namespace, integration_rc_user_text); +CREATE INDEX /*i*/integration_rc_user_text ON integration_recentchanges (integration_rc_user_text, integration_rc_timestamp); + +COMMIT; \ No newline at end of file Added: trunk/extensions/InterwikiIntegration/interwikiintegration-watchlist.sql =================================================================== --- trunk/extensions/InterwikiIntegration/interwikiintegration-watchlist.sql (rev 0) +++ trunk/extensions/InterwikiIntegration/interwikiintegration-watchlist.sql 2010-06-16 02:41:13 UTC (rev 68114) @@ -0,0 +1,20 @@ +BEGIN; + +CREATE TABLE integration_watchlist ( + -- Key to user.user_id + integration_wl_user int unsigned NOT NULL, + -- Database name of the wiki + integration_wl_db varchar(256) binary NOT NULL, + -- Key to page_namespace + integration_wl_namespace int NOT NULL default 0, + -- Key to page_title + integration_wl_title varchar(255) binary NOT NULL default '', + -- Timestamp when user was last sent a notification e-mail; + -- cleared when the user visits the page. + integration_wl_notificationtimestamp varbinary(14) +); + +CREATE UNIQUE INDEX integration_wl_user ON integration_watchlist (integration_wl_user, integration_wl_namespace, integration_wl_title); +CREATE INDEX integration_namespace_title ON integration_watchlist (integration_wl_namespace, integration_wl_title); + +COMMIT; _______________________________________________ MediaWiki-CVS mailing list MediaWiki-CVS@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs