Maintenance for TitleBlacklist extension.

* Use Message class.
* Remove trailing whitespace from 'titlewhitelist'.
* stylize.php.
* Update .gitignore.

Change-Id: Ie78fa25816808b0a695cc20630097326fb4cf705
This commit is contained in:
Siebrand Mazeland 2012-08-29 15:53:38 +02:00 committed by Antoine Musso
parent 795be73165
commit 16f32456ad
7 changed files with 95 additions and 97 deletions

1
.gitignore vendored
View file

@ -2,3 +2,4 @@
*~
*.kate-swp
.*.swp
.idea

View file

@ -26,12 +26,12 @@ class TitleBlacklistHooks {
# Some places check createpage, while others check create.
# As it stands, upload does createpage, but normalize both
# to the same action, to stop future similar bugs.
if( $action === 'createpage' || $action === 'createtalk' ) {
if ( $action === 'createpage' || $action === 'createtalk' ) {
$action = 'create';
}
if( $action == 'create' || $action == 'edit' || $action == 'upload' ) {
if ( $action == 'create' || $action == 'edit' || $action == 'upload' ) {
$blacklisted = TitleBlacklist::singleton()->userCannot( $title, $user, $action );
if( $blacklisted instanceof TitleBlacklistEntry ) {
if ( $blacklisted instanceof TitleBlacklistEntry ) {
$result = array( $blacklisted->getErrorMessage( 'edit' ),
htmlspecialchars( $blacklisted->getRaw() ),
$title->getFullText() );
@ -53,14 +53,14 @@ class TitleBlacklistHooks {
public static function abortMove( $old, $nt, $user, &$err ) {
$titleBlacklist = TitleBlacklist::singleton();
$blacklisted = $titleBlacklist->userCannot( $nt, $user, 'move' );
if( !$blacklisted ) {
if ( !$blacklisted ) {
$blacklisted = $titleBlacklist->userCannot( $old, $user, 'edit' );
}
if( $blacklisted instanceof TitleBlacklistEntry ) {
$err = wfMsgWikiHtml( $blacklisted->getErrorMessage( 'move' ),
htmlspecialchars( $blacklisted->getRaw() ),
htmlspecialchars( $old->getFullText() ),
htmlspecialchars( $nt->getFullText() ) );
if ( $blacklisted instanceof TitleBlacklistEntry ) {
$err = wfMessage( $blacklisted->getErrorMessage( 'move' ),
$blacklisted->getRaw(),
$old->getFullText(),
$nt->getFullText() )->escaped();
return false;
}
return true;
@ -76,11 +76,11 @@ class TitleBlacklistHooks {
*/
private static function acceptNewUserName( $userName, $permissionsUser, &$err, $override = true ) {
$title = Title::makeTitleSafe( NS_USER, $userName );
$blacklisted = TitleBlacklist::singleton()->userCannot( $title, $permissionsUser,
$blacklisted = TitleBlacklist::singleton()->userCannot( $title, $permissionsUser,
'new-account', $override );
if( $blacklisted instanceof TitleBlacklistEntry ) {
if ( $blacklisted instanceof TitleBlacklistEntry ) {
$message = $blacklisted->getErrorMessage( 'new-account' );
$err = wfMsgWikiHtml( $message, htmlspecialchars( $blacklisted->getRaw() ), $userName );
$err = wfMessage( $message, $blacklisted->getRaw(), $userName )->escaped();
return false;
}
return true;
@ -113,17 +113,17 @@ class TitleBlacklistHooks {
global $wgUser;
$title = $editor->mTitle;
if( $title->getNamespace() == NS_MEDIAWIKI && $title->getDBkey() == 'Titleblacklist' ) {
if ( $title->getNamespace() == NS_MEDIAWIKI && $title->getDBkey() == 'Titleblacklist' ) {
$blackList = TitleBlacklist::singleton();
$bl = $blackList->parseBlacklist( $text );
$ok = $blackList->validate( $bl );
if( count( $ok ) == 0 ) {
if ( count( $ok ) == 0 ) {
return true;
}
$errmsg = wfMsgExt( 'titleblacklist-invalid', array( 'parsemag' ), count( $ok ) );
$errlines = '* <tt>' . implode( "</tt>\n* <tt>", array_map( 'wfEscapeWikiText', $ok ) ) . '</tt>';
$errmsg = wfMessage( 'titleblacklist-invalid')->numParams( count( $ok ) )->text();
$errlines = '* <code>' . implode( "</code>\n* <code>", array_map( 'wfEscapeWikiText', $ok ) ) . '</code>';
$error = Html::openElement( 'div', array( 'class' => 'errorbox' ) ) .
$errmsg .
"\n" .
@ -133,16 +133,16 @@ class TitleBlacklistHooks {
// $error will be displayed by the edit class
return true;
} elseif( !$section ) {
} elseif ( !$section ) {
# Block redirects to nonexistent blacklisted titles
$retitle = Title::newFromRedirect( $text );
if( $retitle !== null && !$retitle->exists() ) {
if ( $retitle !== null && !$retitle->exists() ) {
$blacklisted = TitleBlacklist::singleton()->userCannot( $retitle, $wgUser, 'create' );
if( $blacklisted instanceof TitleBlacklistEntry ) {
if ( $blacklisted instanceof TitleBlacklistEntry ) {
$error = Html::openElement( 'div', array( 'class' => 'errorbox' ) ) .
wfMsg( 'titleblacklist-forbidden-edit',
htmlspecialchars( $blacklisted->getRaw() ),
$retitle->getFullText() ) .
wfMessage( 'titleblacklist-forbidden-edit',
$blacklisted->getRaw(),
$retitle->getFullText() )->escaped() .
Html::closeElement( 'div' ) . "\n" .
Html::element( 'br', array( 'clear' => 'all' ) ) . "\n";
}
@ -162,7 +162,7 @@ class TitleBlacklistHooks {
$text, $summary, $isminor, $iswatch, $section )
{
$title = $article->getTitle();
if( $title->getNamespace() == NS_MEDIAWIKI && $title->getDBkey() == 'Titleblacklist' ) {
if ( $title->getNamespace() == NS_MEDIAWIKI && $title->getDBkey() == 'Titleblacklist' ) {
TitleBlacklist::singleton()->invalidate();
}
return true;

View file

@ -13,7 +13,7 @@ $messages['en'] = array(
'titleblacklist' => "# This is a title blacklist. Titles and users that match a regular expression here cannot be created.
# Use \"#\" for comments.
# This is case insensitive by default",
'titlewhitelist' => "# This is a title whitelist. Use \"#\" for comments.
'titlewhitelist' => "# This is a title whitelist. Use \"#\" for comments.
# This is case insensitive by default",
'titleblacklist-forbidden-edit' => 'The title "$2" has been banned from creation.
It matches the following blacklist entry: <code>$1</code>',

View file

@ -17,7 +17,7 @@
*/
class TitleBlacklist {
private $mBlacklist = null, $mWhitelist = null;
const VERSION = 2; //Blacklist format
const VERSION = 2; // Blacklist format
/**
* Get an instance of this class
@ -39,9 +39,9 @@ class TitleBlacklist {
public function load() {
global $wgTitleBlacklistSources, $wgMemc, $wgTitleBlacklistCaching;
wfProfileIn( __METHOD__ );
//Try to find something in the cache
// Try to find something in the cache
$cachedBlacklist = $wgMemc->get( wfMemcKey( "title_blacklist_entries" ) );
if( is_array( $cachedBlacklist ) && count( $cachedBlacklist ) > 0 && ( $cachedBlacklist[0]->getFormatVersion() == self::VERSION ) ) {
if ( is_array( $cachedBlacklist ) && count( $cachedBlacklist ) > 0 && ( $cachedBlacklist[0]->getFormatVersion() == self::VERSION ) ) {
$this->mBlacklist = $cachedBlacklist;
wfProfileOut( __METHOD__ );
return;
@ -50,7 +50,7 @@ class TitleBlacklist {
$sources = $wgTitleBlacklistSources;
$sources[] = array( 'type' => TBLSRC_MSG );
$this->mBlacklist = array();
foreach( $sources as $source ) {
foreach ( $sources as $source ) {
$this->mBlacklist = array_merge( $this->mBlacklist, $this->parseBlacklist( $this->getBlacklistText( $source ) ) );
}
$wgMemc->set( wfMemcKey( "title_blacklist_entries" ), $this->mBlacklist, $wgTitleBlacklistCaching['expiry'] );
@ -64,12 +64,13 @@ class TitleBlacklist {
global $wgMemc, $wgTitleBlacklistCaching;
wfProfileIn( __METHOD__ );
$cachedWhitelist = $wgMemc->get( wfMemcKey( "title_whitelist_entries" ) );
if( is_array( $cachedWhitelist ) && count( $cachedWhitelist ) > 0 && ( $cachedWhitelist[0]->getFormatVersion() != self::VERSION ) ) {
if ( is_array( $cachedWhitelist ) && count( $cachedWhitelist ) > 0 && ( $cachedWhitelist[0]->getFormatVersion() != self::VERSION ) ) {
$this->mWhitelist = $cachedWhitelist;
wfProfileOut( __METHOD__ );
return;
}
$this->mWhitelist = $this->parseBlacklist( wfMsgForContent( 'titlewhitelist' ) );
$this->mWhitelist = $this->parseBlacklist( wfMessage( 'titlewhitelist' )
->inContentLanguage()->text() );
$wgMemc->set( wfMemcKey( "title_whitelist_entries" ), $this->mWhitelist, $wgTitleBlacklistCaching['expiry'] );
wfProfileOut( __METHOD__ );
}
@ -81,35 +82,35 @@ class TitleBlacklist {
* @return The content of the blacklist source as a string
*/
private static function getBlacklistText( $source ) {
if( !is_array( $source ) || count( $source ) <= 0 ) {
return ''; //Return empty string in error case
if ( !is_array( $source ) || count( $source ) <= 0 ) {
return ''; // Return empty string in error case
}
if( $source['type'] == TBLSRC_MSG ) {
return wfMsgForContent( 'titleblacklist' );
} elseif( $source['type'] == TBLSRC_LOCALPAGE && count( $source ) >= 2 ) {
if ( $source['type'] == TBLSRC_MSG ) {
return wfMessage( 'titleblacklist' )->inContentLanguage()->text();
} elseif ( $source['type'] == TBLSRC_LOCALPAGE && count( $source ) >= 2 ) {
$title = Title::newFromText( $source['src'] );
if( is_null( $title ) ) {
if ( is_null( $title ) ) {
return '';
}
if( $title->getNamespace() == NS_MEDIAWIKI ) { //Use wfMsgForContent() for getting messages
$msg = wfMsgForContent( $title->getText() );
if( !wfEmptyMsg( 'titleblacklist', $msg ) ) {
if ( $title->getNamespace() == NS_MEDIAWIKI ) { // Use wfMsgForContent() for getting messages
$msg = wfMessage( $title->getText() )->inContentLanguage()->text();
if ( !wfMessage( 'titleblacklist', $msg )->isDisabled() ) {
return $msg;
} else {
return '';
}
} else {
$article = new Article( $title );
if( $article->exists() ) {
if ( $article->exists() ) {
$article->followRedirect();
return $article->getContent();
}
}
} elseif( $source['type'] == TBLSRC_URL && count( $source ) >= 2 ) {
} elseif ( $source['type'] == TBLSRC_URL && count( $source ) >= 2 ) {
return self::getHttp( $source['src'] );
} elseif( $source['type'] == TBLSRC_FILE && count( $source ) >= 2 ) {
if( file_exists( $source['src'] ) ) {
} elseif ( $source['type'] == TBLSRC_FILE && count( $source ) >= 2 ) {
if ( file_exists( $source['src'] ) ) {
return file_get_contents( $source['src'] );
} else {
return '';
@ -152,7 +153,7 @@ class TitleBlacklist {
* otherwise FALSE
*/
public function userCannot( $title, $user, $action = 'edit', $override = true ) {
if( $override && self::userCanOverride( $user, $action ) ) {
if ( $override && self::userCanOverride( $user, $action ) ) {
return false;
} else {
return $this->isBlacklisted( $title, $action );
@ -169,13 +170,13 @@ class TitleBlacklist {
* otherwise FALSE
*/
public function isBlacklisted( $title, $action = 'edit' ) {
if( !($title instanceof Title) ) {
if ( !( $title instanceof Title ) ) {
$title = Title::newFromText( $title );
}
$blacklist = $this->getBlacklist();
foreach ( $blacklist as $item ) {
if( $item->matches( $title, $action ) ) {
if( $this->isWhitelisted( $title, $action ) ) {
if ( $item->matches( $title, $action ) ) {
if ( $this->isWhitelisted( $title, $action ) ) {
return false;
}
return $item; // "returning true"
@ -193,12 +194,12 @@ class TitleBlacklist {
* @return bool TRUE if whitelisted; otherwise FALSE
*/
public function isWhitelisted( $title, $action = 'edit' ) {
if( !($title instanceof Title) ) {
if ( !( $title instanceof Title ) ) {
$title = Title::newFromText( $title );
}
$whitelist = $this->getWhitelist();
foreach( $whitelist as $item ) {
if( $item->matches( $title, $action ) ) {
foreach ( $whitelist as $item ) {
if ( $item->matches( $title, $action ) ) {
return true;
}
}
@ -211,7 +212,7 @@ class TitleBlacklist {
* @return Array of TitleBlacklistEntry items
*/
public function getBlacklist() {
if( is_null( $this->mBlacklist ) ) {
if ( is_null( $this->mBlacklist ) ) {
$this->load();
}
return $this->mBlacklist;
@ -223,7 +224,7 @@ class TitleBlacklist {
* @return Array of TitleBlacklistEntry items
*/
public function getWhitelist() {
if( is_null( $this->mWhitelist ) ) {
if ( is_null( $this->mWhitelist ) ) {
$this->loadWhitelist();
}
return $this->mWhitelist;
@ -265,10 +266,10 @@ class TitleBlacklist {
*/
public function validate( $blacklist ) {
$badEntries = array();
foreach( $blacklist as $e ) {
foreach ( $blacklist as $e ) {
wfSuppressWarnings();
$regex = $e->getRegex();
if( preg_match( "/{$regex}/u", '' ) === false ) {
if ( preg_match( "/{$regex}/u", '' ) === false ) {
$badEntries[] = $e->getRaw();
}
wfRestoreWarnings();
@ -295,10 +296,10 @@ class TitleBlacklist {
*/
class TitleBlacklistEntry {
private
$mRaw, ///< Raw line
$mRegex, ///< Regular expression to match
$mParams, ///< Parameters for this entry
$mFormatVersion; ///< Entry format version
$mRaw, /// < Raw line
$mRegex, /// < Regular expression to match
$mParams, /// < Parameters for this entry
$mFormatVersion; /// < Entry format version
/**
* Construct a new TitleBlacklistEntry.
@ -332,17 +333,17 @@ class TitleBlacklistEntry {
wfRestoreWarnings();
global $wgUser;
if( $match ) {
if( isset( $this->mParams['autoconfirmed'] ) && $wgUser->isAllowed( 'autoconfirmed' ) ) {
if ( $match ) {
if ( isset( $this->mParams['autoconfirmed'] ) && $wgUser->isAllowed( 'autoconfirmed' ) ) {
return false;
}
if( isset( $this->mParams['moveonly'] ) && $action != 'move' ) {
if ( isset( $this->mParams['moveonly'] ) && $action != 'move' ) {
return false;
}
if( isset( $this->mParams['newaccountonly'] ) && $action != 'new-account' ) {
if ( isset( $this->mParams['newaccountonly'] ) && $action != 'new-account' ) {
return false;
}
if( !isset( $this->mParams['noedit'] ) && $action == 'edit' ) {
if ( !isset( $this->mParams['noedit'] ) && $action == 'edit' ) {
return false;
}
if ( isset( $this->mParams['reupload'] ) && $action == 'upload' ) {
@ -374,50 +375,50 @@ class TitleBlacklistEntry {
$opts_str = trim( $opts_str );
// Parse opts
$opts = preg_split( '/\s*\|\s*/', $opts_str );
foreach( $opts as $opt ) {
foreach ( $opts as $opt ) {
$opt2 = strtolower( $opt );
if( $opt2 == 'autoconfirmed' ) {
if ( $opt2 == 'autoconfirmed' ) {
$options['autoconfirmed'] = true;
}
if( $opt2 == 'moveonly' ) {
if ( $opt2 == 'moveonly' ) {
$options['moveonly'] = true;
}
if( $opt2 == 'newaccountonly' ) {
if ( $opt2 == 'newaccountonly' ) {
$options['newaccountonly'] = true;
}
if( $opt2 == 'noedit' ) {
if ( $opt2 == 'noedit' ) {
$options['noedit'] = true;
}
if( $opt2 == 'casesensitive' ) {
if ( $opt2 == 'casesensitive' ) {
$options['casesensitive'] = true;
}
if( $opt2 == 'reupload' ) {
if ( $opt2 == 'reupload' ) {
$options['reupload'] = true;
}
if( preg_match( '/errmsg\s*=\s*(.+)/i', $opt, $matches ) ) {
if ( preg_match( '/errmsg\s*=\s*(.+)/i', $opt, $matches ) ) {
$options['errmsg'] = $matches[1];
}
}
// Process magic words
preg_match_all( '/{{\s*([a-z]+)\s*:\s*(.+?)\s*}}/', $regex, $magicwords, PREG_SET_ORDER );
foreach( $magicwords as $mword ) {
foreach ( $magicwords as $mword ) {
global $wgParser; // Functions we're calling don't need, nevertheless let's use it
switch( strtolower( $mword[1] ) ) {
case 'ns':
$cpf_result = CoreParserFunctions::ns( $wgParser, $mword[2] );
if( is_string( $cpf_result ) ) {
if ( is_string( $cpf_result ) ) {
$regex = str_replace( $mword[0], $cpf_result, $regex ); // All result will have the same value, so we can just use str_seplace()
}
break;
case 'int':
$cpf_result = wfMsgForContent( $mword[2] );
if( is_string( $cpf_result ) ) {
$cpf_result = wfMessage( $mword[2] )->inContentLanguage()->text();
if ( is_string( $cpf_result ) ) {
$regex = str_replace( $mword[0], $cpf_result, $regex );
}
}
}
// Return result
if( $regex ) {
if ( $regex ) {
return new TitleBlacklistEntry( $regex, $options, $raw );
} else {
return null;

View file

@ -1,9 +1,9 @@
<?php
if ( !defined( 'MEDIAWIKI' ) ) {
exit(1);
exit( 1 );
}
//@{
// @{
/**
* @file
* @ingroup Extensions
@ -18,17 +18,18 @@ $wgExtensionCredits['antispam'][] = array(
'descriptionmsg' => 'titleblacklist-desc',
);
$wgExtensionMessagesFiles['TitleBlacklist'] = dirname( __FILE__ ) . '/TitleBlacklist.i18n.php';
$wgAutoloadClasses['TitleBlacklist'] = dirname( __FILE__ ) . '/TitleBlacklist.list.php';
$wgAutoloadClasses['TitleBlacklistHooks'] = dirname( __FILE__ ) . '/TitleBlacklist.hooks.php';
$dir = __DIR__;
$wgExtensionMessagesFiles['TitleBlacklist'] = $dir . '/TitleBlacklist.i18n.php';
$wgAutoloadClasses['TitleBlacklist'] = $dir . '/TitleBlacklist.list.php';
$wgAutoloadClasses['TitleBlacklistHooks'] = $dir . '/TitleBlacklist.hooks.php';
/** @defgroup Title blacklist source types
* @{
*/
define( 'TBLSRC_MSG', 0 ); ///< For internal usage
define( 'TBLSRC_LOCALPAGE', 1 ); ///< Local wiki page
define( 'TBLSRC_URL', 2 ); ///< Load blacklist from URL
define( 'TBLSRC_FILE', 3 ); ///< Load from file
define( 'TBLSRC_MSG', 0 ); ///< For internal usage
define( 'TBLSRC_LOCALPAGE', 1 ); ///< Local wiki page
define( 'TBLSRC_URL', 2 ); ///< Load blacklist from URL
define( 'TBLSRC_FILE', 3 ); ///< Load from file
/** @} */
/** Array of title blacklist sources */
@ -46,8 +47,8 @@ $dir = dirname( __FILE__ );
$wgAutoloadClasses['ApiQueryTitleBlacklist'] = "$dir/api/ApiQueryTitleBlacklist.php";
$wgAPIModules['titleblacklist'] = 'ApiQueryTitleBlacklist';
$wgAvailableRights[] = 'tboverride'; // Implies tboverride-account
$wgAvailableRights[] = 'tboverride-account'; // For account creation
$wgAvailableRights[] = 'tboverride'; // Implies tboverride-account
$wgAvailableRights[] = 'tboverride-account'; // For account creation
$wgGroupPermissions['sysop']['tboverride'] = true;
$wgHooks['getUserPermissionsErrorsExpensive'][] = 'TitleBlacklistHooks::userCan';
@ -59,4 +60,4 @@ $wgHooks['EditFilter'][] = 'TitleBlacklistHooks::validateBlacklist';
$wgHooks['ArticleSaveComplete'][] = 'TitleBlacklistHooks::clearBlacklist';
$wgHooks['UserCreateForm'][] = 'TitleBlacklistHooks::addOverrideCheckbox';
//@}
// @}

View file

@ -34,10 +34,6 @@ class ApiQueryTitleBlacklist extends ApiBase {
}
public function execute() {
# get the current user.
$context = $this->getContext();
$user = $context->getUser();
$params = $this->extractRequestParams();
$action = $params['action'];
@ -46,7 +42,7 @@ class ApiQueryTitleBlacklist extends ApiBase {
// Some places check createpage, while others check create.
// As it stands, upload does createpage, but normalize both
// to the same action, to stop future similar bugs.
if( $action === 'createpage' || $action === 'createtalk' ) {
if ( $action === 'createpage' || $action === 'createtalk' ) {
$action = 'create';
}
@ -55,8 +51,8 @@ class ApiQueryTitleBlacklist extends ApiBase {
$this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
}
$blacklisted = TitleBlacklist::singleton()->userCannot( $title, $user, $action );
if( $blacklisted instanceof TitleBlacklistEntry ) {
$blacklisted = TitleBlacklist::singleton()->userCannot( $title, $this->getUser(), $action );
if ( $blacklisted instanceof TitleBlacklistEntry ) {
// this title is blacklisted.
$result = array(
htmlspecialchars( $blacklisted->getRaw() ),
@ -74,7 +70,6 @@ class ApiQueryTitleBlacklist extends ApiBase {
// not blacklisted
$this->getResult()->addValue( 'titleblacklist', 'result', 'ok' );
}
}
public function getAllowedParams() {

View file

@ -11,7 +11,7 @@
* Ian Baker <ian@wikimedia.org>
*/
ini_set( 'include_path', ini_get('include_path') . ':' . __DIR__ . '/../../../tests/phpunit/includes/api' );
ini_set( 'include_path', ini_get( 'include_path' ) . ':' . __DIR__ . '/../../../tests/phpunit/includes/api' );
class ApiQueryTitleBlacklistTest extends ApiTestCase {