A LOT of function level documentation

This commit is contained in:
Sam Reed 2012-03-11 20:40:04 +00:00
parent c1e83a2245
commit 0c99b2bc15
Notes: Raimond Spekking 2012-03-12 20:46:25 +00:00
3 changed files with 594 additions and 21 deletions

View file

@ -120,6 +120,10 @@ class AbuseFilter {
);
public static $editboxName = null;
/**
* @param $context IContextSource
* @param $pageType
*/
public static function addNavigationLinks( IContextSource $context, $pageType ) {
$linkDefs = array(
'home' => 'Special:AbuseFilter',
@ -159,7 +163,7 @@ class AbuseFilter {
if ( $name == $pageType ) {
$links[] = Xml::tags( 'strong', null, $msg );
} else {
$links[] = $context->getSkin()->link( $title, $msg );
$links[] = Linker::link( $title, $msg );
}
}
@ -192,6 +196,9 @@ class AbuseFilter {
return $vars;
}
/**
* @return array
*/
public static function getBuilderValues() {
static $realValues = null;
@ -205,6 +212,10 @@ class AbuseFilter {
return $realValues;
}
/**
* @param $filter
* @return bool
*/
public static function filterHidden( $filter ) {
$globalIndex = self::decodeGlobalName( $filter );
if ( $globalIndex ) {
@ -226,6 +237,10 @@ class AbuseFilter {
return $hidden ? true : false;
}
/**
* @param $val int
* @throws MWException
*/
public static function triggerLimiter( $val = 1 ) {
self::$condCount += $val;
@ -242,9 +257,8 @@ class AbuseFilter {
}
/**
* @static
* @param $title Title
* @param $prefix
* @param $title Title
* @param $prefix
* @return AbuseFilterVariableHolder
*/
public static function generateTitleVars( $title, $prefix ) {
@ -280,6 +294,10 @@ class AbuseFilter {
return $vars;
}
/**
* @param $filter
* @return mixed
*/
public static function checkSyntax( $filter ) {
global $wgAbuseFilterParserClass;
@ -288,6 +306,11 @@ class AbuseFilter {
return $parser->checkSyntax( $filter );
}
/**
* @param $expr
* @param array $vars
* @return string
*/
public static function evaluateExpression( $expr, $vars = array() ) {
global $wgAbuseFilterParserClass;
@ -302,6 +325,14 @@ class AbuseFilter {
return $parser->evaluateExpression( $expr );
}
/**
* @param $conds
* @param $vars
* @param $ignoreError bool
* @param $keepVars string
* @return bool
* @throws Exception
*/
public static function checkConditions(
$conds,
$vars,
@ -392,6 +423,14 @@ class AbuseFilter {
return $filter_matched;
}
/**
* @static
* @param $row
* @param $vars
* @param $profile bool
* @param $prefix string
* @return bool
*/
public static function checkFilter( $row, $vars, $profile = false, $prefix = '' ) {
$filterID = $prefix . $row->af_id;
@ -431,6 +470,9 @@ class AbuseFilter {
return $result;
}
/**
* @param $filter
*/
public static function resetFilterProfile( $filter ) {
global $wgMemc;
$countKey = wfMemcKey( 'abusefilter', 'profile', $filter, 'count' );
@ -440,6 +482,11 @@ class AbuseFilter {
$wgMemc->delete( $totalKey );
}
/**
* @param $filter
* @param $time
* @param $conds
*/
public static function recordProfilingResult( $filter, $time, $conds ) {
global $wgMemc;
@ -462,6 +509,10 @@ class AbuseFilter {
}
}
/**
* @param $filter
* @return array
*/
public static function getFilterProfile( $filter ) {
global $wgMemc;
@ -491,7 +542,7 @@ class AbuseFilter {
*
* @param $filter string
*
* @return string|false
* @return string|bool
*/
public static function decodeGlobalName( $filter ) {
if ( strpos( $filter, 'global-' ) == 0 ) {
@ -501,6 +552,10 @@ class AbuseFilter {
return false;
}
/**
* @param $filters array
* @return array
*/
public static function getConsequencesForFilters( $filters ) {
$globalFilters = array();
$localFilters = array();
@ -536,6 +591,12 @@ class AbuseFilter {
return $consequences;
}
/**
* @param $dbr DatabaseBase
* @param $filters array
* @param $prefix string
* @return array
*/
public static function loadConsequencesFromDB( $dbr, $filters, $prefix = '' ) {
$actionsByFilter = array();
foreach ( $filters as $filter ) {
@ -670,6 +731,11 @@ class AbuseFilter {
return array( $actionsTaken, implode( "\n", $messages ) );
}
/**
* @param $vars AbuseFilterVariableHolder
* @param $title
* @return bool
*/
public static function filterAction( $vars, $title ) {
global $wgUser, $wgTitle;
@ -731,6 +797,13 @@ class AbuseFilter {
return $error_msg;
}
/**
* @param $actions_taken
* @param $log_template
* @param $action
* @param $vars AbuseFilterVariableHolder
* @return mixed
*/
public static function addLogEntries( $actions_taken, $log_template, $action, $vars ) {
wfProfileIn( __METHOD__ );
$dbw = wfGetDB( DB_MASTER );
@ -961,6 +1034,14 @@ class AbuseFilter {
return $obj;
}
/**
* @param $action
* @param $parameters
* @param $title
* @param $vars AbuseFilterVariableHolder
* @param $rule_desc
* @return string
*/
public static function takeConsequenceAction( $action, $parameters, $title,
$vars, $rule_desc )
{
@ -1120,6 +1201,14 @@ class AbuseFilter {
return $display;
}
/**
* @param $throttleId
* @param $types
* @param $title
* @param $rateCount
* @param $ratePeriod
* @return bool
*/
public static function isThrottled( $throttleId, $types, $title, $rateCount, $ratePeriod ) {
global $wgMemc;
@ -1148,6 +1237,11 @@ class AbuseFilter {
return false; // NOT THROTTLED
}
/**
* @param $type
* @param $title Title
* @return Int|string
*/
public static function throttleIdentifier( $type, $title ) {
global $wgUser;
@ -1178,6 +1272,12 @@ class AbuseFilter {
return $identifier;
}
/**
* @param $throttleId
* @param $type
* @param $title Title
* @return String
*/
public static function throttleKey( $throttleId, $type, $title ) {
$types = explode( ',', $type );
@ -1192,10 +1292,17 @@ class AbuseFilter {
return wfMemcKey( 'abusefilter', 'throttle', $throttleId, $type, $identifier );
}
/**
* @param $user User
* @return String
*/
public static function autoPromoteBlockKey( $user ) {
return wfMemcKey( 'abusefilter', 'block-autopromote', $user->getId() );
}
/**
* @param $filters
*/
public static function recordStats( $filters ) {
global $wgAbuseFilterConditionLimit, $wgMemc;
@ -1234,6 +1341,10 @@ class AbuseFilter {
wfProfileOut( __METHOD__ );
}
/**
* @param $filters
* @param $total
*/
public static function checkEmergencyDisable( $filters, $total ) {
global $wgAbuseFilterEmergencyDisableThreshold, $wgAbuseFilterEmergencyDisableCount,
$wgAbuseFilterEmergencyDisableAge, $wgMemc;
@ -1272,18 +1383,31 @@ class AbuseFilter {
}
}
/**
* @return String
*/
public static function filterLimitReachedKey() {
return wfMemcKey( 'abusefilter', 'stats', 'overflow' );
}
/**
* @return String
*/
public static function filterUsedKey() {
return wfMemcKey( 'abusefilter', 'stats', 'total' );
}
/**
* @param $filter
* @return String
*/
public static function filterMatchesKey( $filter = null ) {
return wfMemcKey( 'abusefilter', 'stats', 'matches', $filter );
}
/**
* @return User
*/
public static function getFilterUser() {
$user = User::newFromName( wfMsgForContent( 'abusefilter-blocker' ) );
$user->load();
@ -1318,6 +1442,7 @@ class AbuseFilter {
* @param $textName String
* @param $addResultDiv Boolean
* @param $canEdit Boolean
* @return string
*/
static function buildEditBox( $rules, $textName = 'wpFilterRules', $addResultDiv = true,
$canEdit = true ) {
@ -1442,6 +1567,10 @@ class AbuseFilter {
return array_unique( $differences );
}
/**
* @param $row
* @return array
*/
static function translateFromHistory( $row ) {
# Translate into an abuse_filter row with some black magic.
# This is ever so slightly evil!
@ -1477,12 +1606,20 @@ class AbuseFilter {
return array( $af_row, $actions_output );
}
/**
* @param $action string
* @return String
*/
static function getActionDisplay( $action ) {
$display = wfMsg( "abusefilter-action-$action" );
$display = wfEmptyMsg( "abusefilter-action-$action", $display ) ? $action : $display;
return $display;
}
/**
* @param $row
* @return AbuseFilterVariableHolder|null
*/
public static function getVarsFromRCRow( $row ) {
if ( $row->rc_this_oldid ) {
// It's an edit.
@ -1502,6 +1639,10 @@ class AbuseFilter {
return $vars;
}
/**
* @param $row
* @return AbuseFilterVariableHolder
*/
public static function getCreateVarsFromRCRow( $row ) {
$vars = new AbuseFilterVariableHolder;
@ -1518,6 +1659,10 @@ class AbuseFilter {
return $vars;
}
/**
* @param $row
* @return AbuseFilterVariableHolder
*/
public static function getEditVarsFromRCRow( $row ) {
$vars = new AbuseFilterVariableHolder;
$title = Title::makeTitle( $row->rc_namespace, $row->rc_title );
@ -1551,6 +1696,10 @@ class AbuseFilter {
return $vars;
}
/**
* @param $row
* @return AbuseFilterVariableHolder
*/
public static function getMoveVarsFromRCRow( $row ) {
$vars = new AbuseFilterVariableHolder;
@ -1580,8 +1729,8 @@ class AbuseFilter {
}
/**
* @static
* @param $title Title
* @param $title Title
* @param $article Array
* @return AbuseFilterVariableHolder
*/
public static function getEditVars( $title, $article = null ) {
@ -1640,6 +1789,10 @@ class AbuseFilter {
return $vars;
}
/**
* @param $vars AbuseFilterVariableHolder
* @return string
*/
public static function buildVarDumpTable( $vars ) {
// Export all values
if ( $vars instanceof AbuseFilterVariableHolder ) {
@ -1693,20 +1846,32 @@ class AbuseFilter {
return $output;
}
/**
* @param $page
* @param $type
* @param $title Title
* @param $sk Skin
* @param $args array
* @return String
*/
static function modifyActionText( $page, $type, $title, $sk, $args ) {
list( $history_id, $filter_id ) = $args;
$filter_link = $sk ? $sk->link( $title ) : $title->getCanonicalURL();
$filter_link = Linker::link( $title );
$details_title = SpecialPage::getTitleFor( 'AbuseFilter', "history/$filter_id/diff/prev/$history_id" );
$details_text = wfMsgExt( 'abusefilter-log-detailslink', 'parseinline' );
$details_link =
$sk ? $sk->link( $details_title, $details_text ) : $details_title->getCanonicalURL();
$details_link = Linker::link( $details_title, $details_text );
return wfMsgExt( 'abusefilter-log-entry-modify',
array( 'parseinline', 'replaceafter' ), array( $filter_link, $details_link ) );
}
/**
* @param $action
* @param $parameters
* @return String
*/
static function formatAction( $action, $parameters ) {
global $wgLang;
if ( count( $parameters ) == 0 ) {
@ -1719,6 +1884,10 @@ class AbuseFilter {
return $displayAction;
}
/**
* @param $value array
* @return string
*/
static function formatFlags( $value ) {
global $wgLang;
$flags = array_filter( explode( ',', $value ) );
@ -1729,6 +1898,9 @@ class AbuseFilter {
return $wgLang->commaList( $flags_display );
}
/**
* @param $data string
*/
static function sendToUDP( $data ) {
global $wgAbuseFilterUDPPrefix, $wgAbuseFilterUDPAddress, $wgAbuseFilterUDPPort;
@ -1740,11 +1912,15 @@ class AbuseFilter {
);
}
/**
* @param $filterID
* @return bool|mixed|string
*/
static function getGlobalFilterDescription( $filterID ) {
global $wgAbuseFilterCentralDB;
if ( !$wgAbuseFilterCentralDB ) {
return;
return '';
}
$fdb = wfGetDB( DB_SLAVE, array(), $wgAbuseFilterCentralDB );

View file

@ -79,6 +79,11 @@ class AFPData {
$this->data = $val;
}
/**
* @param $var
* @return AFPData
* @throws AFPException
*/
public static function newFromPHPVar( $var ) {
if ( is_string( $var ) ) {
return new AFPData( self::DString, $var );
@ -103,10 +108,19 @@ class AFPData {
}
}
/**
* @return AFPData
*/
public function dup() {
return new AFPData( $this->type, $this->data );
}
/**
* @static
* @param $orig
* @param $target
* @return AFPData
*/
public static function castTypes( $orig, $target ) {
if ( $orig->type == $target ) {
return $orig->dup();
@ -120,7 +134,7 @@ class AFPData {
return new AFPData( self::DBool, (bool)count( $orig->data ) );
}
if ( $target == self::DFloat ) {
return new AFPData( self::DFloat, doubleval( count( $orig->data ) ) );
return new AFPData( self::DFloat, floatval( count( $orig->data ) ) );
}
if ( $target == self::DInt ) {
return new AFPData( self::DInt, intval( count( $orig->data ) ) );
@ -138,7 +152,7 @@ class AFPData {
return new AFPData( self::DBool, (bool)$orig->data );
}
if ( $target == self::DFloat ) {
return new AFPData( self::DFloat, doubleval( $orig->data ) );
return new AFPData( self::DFloat, floatval( $orig->data ) );
}
if ( $target == self::DInt ) {
return new AFPData( self::DInt, intval( $orig->data ) );
@ -151,14 +165,28 @@ class AFPData {
}
}
/**
* @param $value
* @return AFPData
*/
public static function boolInvert( $value ) {
return new AFPData( self::DBool, !$value->toBool() );
}
/**
* @param $base
* @param $exponent
* @return AFPData
*/
public static function pow( $base, $exponent ) {
return new AFPData( self::DFloat, pow( $base->toFloat(), $exponent->toFloat() ) );
}
/**
* @param $a
* @param $b
* @return AFPData
*/
public static function keywordIn( $a, $b ) {
$a = $a->toString();
$b = $b->toString();
@ -170,6 +198,11 @@ class AFPData {
return new AFPData( self::DBool, in_string( $a, $b ) );
}
/**
* @param $a
* @param $b
* @return AFPData
*/
public static function keywordContains( $a, $b ) {
$a = $a->toString();
$b = $b->toString();
@ -181,6 +214,11 @@ class AFPData {
return new AFPData( self::DBool, in_string( $b, $a ) );
}
/**
* @param $value
* @param $list
* @return bool
*/
public static function listContains( $value, $list ) {
// Should use built-in PHP function somehow
foreach ( $list->data as $item ) {
@ -191,11 +229,21 @@ class AFPData {
return false;
}
/**
* @param $d1
* @param $d2
* @return bool
*/
public static function equals( $d1, $d2 ) {
return $d1->type != self::DList && $d2->type != self::DList &&
$d1->toString() === $d2->toString();
}
/**
* @param $str
* @param $pattern
* @return AFPData
*/
public static function keywordLike( $str, $pattern ) {
$str = $str->toString();
$pattern = $pattern->toString();
@ -205,6 +253,14 @@ class AFPData {
return new AFPData( self::DBool, (bool)$result );
}
/**
* @param $str
* @param $regex
* @param $pos
* @param $insensitive bool
* @return AFPData
* @throws Exception
*/
public static function keywordRegex( $str, $regex, $pos, $insensitive = false ) {
$str = $str->toString();
$pattern = $regex->toString();
@ -228,10 +284,20 @@ class AFPData {
return new AFPData( self::DBool, (bool)$result );
}
/**
* @param $str
* @param $regex
* @param $pos
* @return AFPData
*/
public static function keywordRegexInsensitive( $str, $regex, $pos ) {
return self::keywordRegex( $str, $regex, $pos, true );
}
/**
* @param $data
* @return AFPData
*/
public static function unaryMinus( $data ) {
if ( $data->type == self::DInt ) {
return new AFPData( $data->type, - $data->toInt() );
@ -240,6 +306,13 @@ class AFPData {
}
}
/**
* @param $a
* @param $b
* @param $op
* @return AFPData
* @throws AFPException
*/
public static function boolOp( $a, $b, $op ) {
$a = $a->toBool();
$b = $b->toBool();
@ -255,6 +328,13 @@ class AFPData {
throw new AFPException( "Invalid boolean operation: {$op}" ); // Should never happen.
}
/**
* @param $a
* @param $b
* @param $op
* @return AFPData
* @throws AFPException
*/
public static function compareOp( $a, $b, $op ) {
if ( $op == '==' || $op == '=' ) {
return new AFPData( self::DBool, self::equals( $a, $b ) );
@ -285,6 +365,15 @@ class AFPData {
throw new AFPException( "Invalid comparison operation: {$op}" ); // Should never happen
}
/**
* @param $a
* @param $b
* @param $op
* @param $pos
* @return AFPData
* @throws AFPUserVisibleException
* @throws AFPException
*/
public static function mulRel( $a, $b, $op, $pos ) {
// Figure out the type.
if ( $a->type == self::DFloat || $b->type == self::DFloat ||
@ -315,12 +404,17 @@ class AFPData {
if ( $type == self::DInt ) {
$data = intval( $data );
} else {
$data = doubleval( $data );
$data = floatval( $data );
}
return new AFPData( $type, $data );
}
/**
* @param $a
* @param $b
* @return AFPData
*/
public static function sum( $a, $b ) {
if ( $a->type == self::DString || $b->type == self::DString ) {
return new AFPData( self::DString, $a->toString() . $b->toString() );
@ -331,6 +425,11 @@ class AFPData {
}
}
/**
* @param $a
* @param $b
* @return AFPData
*/
public static function sub( $a, $b ) {
return new AFPData( self::DFloat, $a->toFloat() - $b->toFloat() );
}
@ -338,6 +437,7 @@ class AFPData {
/** Convert shorteners */
/**
* @throws MWException
* @return mixed
*/
public function toNative() {
@ -434,6 +534,15 @@ class AFPRegexErrorHandler {
$this->pos = $pos;
}
/**
* @param $errno
* @param $errstr
* @param $errfile
* @param $errline
* @param $context
* @return bool
* @throws AFPUserVisibleException
*/
function handleError( $errno, $errstr, $errfile, $errline, $context ) {
if ( error_reporting() == 0 ) {
return true;
@ -455,7 +564,12 @@ class AFPRegexErrorHandler {
}
class AbuseFilterParser {
var $mParams, $mVars, $mCode, $mTokens, $mPos, $mCur, $mShortCircuit, $mAllowShort;
var $mParams, $mCode, $mTokens, $mPos, $mCur, $mShortCircuit, $mAllowShort, $mLen;
/**
* @var AbuseFilterVariableHolder
*/
var $mVars;
// length,lcase,ccnorm,rmdoubles,specialratio,rmspecials,norm,count
static $mFunctions = array(
@ -529,6 +643,10 @@ class AbuseFilterParser {
$this->mAllowShort = true;
}
/**
* @param $filter
* @return array|bool
*/
public function checkSyntax( $filter ) {
try {
$origAS = $this->mAllowShort;
@ -542,11 +660,18 @@ class AbuseFilterParser {
return true;
}
/**
* @param $name
* @param $value
*/
public function setVar( $name, $value ) {
$name = strtolower( $name );
$this->mVars->setVar( $name, $value );
}
/**
* @param $vars
*/
public function setVars( $vars ) {
if ( is_array( $vars ) ) {
foreach ( $vars as $name => $var ) {
@ -557,6 +682,9 @@ class AbuseFilterParser {
}
}
/**
* @return AFPToken
*/
protected function move( ) {
wfProfileIn( __METHOD__ );
list( $val, $type, $code, $offset ) =
@ -568,17 +696,28 @@ class AbuseFilterParser {
return $this->mCur = $token;
}
// getState() and setState() function allows parser state to be rollbacked to several tokens back
/**
* getState() function allows parser state to be rollbacked to several tokens back
* @return AFPParserState
*/
protected function getState() {
return new AFPParserState( $this->mCur, $this->mPos );
}
/**
* setState() function allows parser state to be rollbacked to several tokens back
* @param AFPParserState $state
*/
protected function setState( AFPParserState $state ) {
$this->mCur = $state->token;
$this->mPos = $state->pos;
self::$lastHandledToken = $state->lastInput;
}
/**
* @return mixed
* @throws AFPUserVisibleException
*/
protected function skipOverBraces() {
if ( !( $this->mCur->type == AFPToken::TBrace && $this->mCur->value == '(' ) || !$this->mShortCircuit ) {
return;
@ -601,14 +740,26 @@ class AbuseFilterParser {
throw new AFPUserVisibleException( 'expectednotfound', $this->mCur->pos, array( ')' ) );
}
/**
* @param $code
* @return bool
*/
public function parse( $code ) {
return $this->intEval( $code )->toBool();
}
/**
* @param $filter
* @return string
*/
public function evaluateExpression( $filter ) {
return $this->intEval( $filter )->toString();
}
/**
* @param $code
* @return AFPData
*/
function intEval( $code ) {
// Setup, resetting
$this->mCode = $code;
@ -621,6 +772,11 @@ class AbuseFilterParser {
return $result;
}
/**
* @param $a
* @param $b
* @return int
*/
static function lengthCompare( $a, $b ) {
if ( strlen( $a ) == strlen( $b ) ) {
return 0;
@ -635,6 +791,7 @@ class AbuseFilterParser {
* Handles unexpected characters after the expression
*
* @param $result
* @throws AFPUserVisibleException
*/
protected function doLevelEntry( &$result ) {
$this->doLevelSemicolon( $result );
@ -661,6 +818,8 @@ class AbuseFilterParser {
* Handles multiple expressions
*
* @param $result
* @throws AFPUserVisibleException
* @return
*/
protected function doLevelSet( &$result ) {
if ( $this->mCur->type == AFPToken::TID ) {
@ -724,6 +883,10 @@ class AbuseFilterParser {
$this->doLevelConditions( $result );
}
/**
* @param $result
* @throws AFPUserVisibleException
*/
protected function doLevelConditions( &$result ) {
if ( $this->mCur->type == AFPToken::TKeyword && $this->mCur->value == 'if' ) {
$this->move();
@ -838,6 +1001,9 @@ class AbuseFilterParser {
}
}
/**
* @param $result
*/
protected function doLevelBoolOps( &$result ) {
$this->doLevelCompares( $result );
$ops = array( '&', '|', '^' );
@ -876,6 +1042,9 @@ class AbuseFilterParser {
}
}
/**
* @param $result
*/
protected function doLevelCompares( &$result ) {
AbuseFilter::triggerLimiter();
$this->doLevelSumRels( $result );
@ -891,6 +1060,9 @@ class AbuseFilterParser {
}
}
/**
* @param $result
*/
protected function doLevelSumRels( &$result ) {
$this->doLevelMulRels( $result );
wfProfileIn( __METHOD__ );
@ -910,6 +1082,9 @@ class AbuseFilterParser {
wfProfileOut( __METHOD__ );
}
/**
* @param $result
*/
protected function doLevelMulRels( &$result ) {
$this->doLevelPow( $result );
wfProfileIn( __METHOD__ );
@ -924,6 +1099,9 @@ class AbuseFilterParser {
wfProfileOut( __METHOD__ );
}
/**
* @param $result
*/
protected function doLevelPow( &$result ) {
$this->doLevelBoolInvert( $result );
wfProfileIn( __METHOD__ );
@ -936,6 +1114,9 @@ class AbuseFilterParser {
wfProfileOut( __METHOD__ );
}
/**
* @param $result
*/
protected function doLevelBoolInvert( &$result ) {
if ( $this->mCur->type == AFPToken::TOp && $this->mCur->value == '!' ) {
$this->move();
@ -948,6 +1129,9 @@ class AbuseFilterParser {
}
}
/**
* @param $result
*/
protected function doLevelSpecialWords( &$result ) {
$this->doLevelUnarys( $result );
$keyword = strtolower( $this->mCur->value );
@ -979,6 +1163,9 @@ class AbuseFilterParser {
}
}
/**
* @param $result
*/
protected function doLevelUnarys( &$result ) {
$op = $this->mCur->value;
if ( $this->mCur->type == AFPToken::TOp && ( $op == "+" || $op == "-" ) ) {
@ -994,6 +1181,10 @@ class AbuseFilterParser {
}
}
/**
* @param $result
* @throws AFPUserVisibleException
*/
protected function doLevelListElements( &$result ) {
$this->doLevelBraces( $result );
while ( $this->mCur->type == AFPToken::TSquareBracket && $this->mCur->value == '[' ) {
@ -1017,6 +1208,10 @@ class AbuseFilterParser {
}
}
/**
* @param $result
* @throws AFPUserVisibleException
*/
protected function doLevelBraces( &$result ) {
if ( $this->mCur->type == AFPToken::TBrace && $this->mCur->value == '(' ) {
if ( $this->mShortCircuit ) {
@ -1036,6 +1231,10 @@ class AbuseFilterParser {
}
}
/**
* @param $result
* @throws AFPUserVisibleException
*/
protected function doLevelFunction( &$result ) {
if ( $this->mCur->type == AFPToken::TID && isset( self::$mFunctions[$this->mCur->value] ) ) {
wfProfileIn( __METHOD__ );
@ -1104,6 +1303,11 @@ class AbuseFilterParser {
}
}
/**
* @param $result
* @throws AFPUserVisibleException
* @return AFPData
*/
protected function doLevelAtom( &$result ) {
wfProfileIn( __METHOD__ );
$tok = $this->mCur->value;
@ -1186,6 +1390,11 @@ class AbuseFilterParser {
/* End of levels */
/**
* @param $var
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function getVarValue( $var ) {
wfProfileIn( __METHOD__ );
$var = strtolower( $var );
@ -1206,6 +1415,11 @@ class AbuseFilterParser {
}
}
/**
* @param $name
* @param $value
* @throws AFPUserVisibleException
*/
protected function setUserVariable( $name, $value ) {
$builderValues = AbuseFilter::getBuilderValues();
if ( array_key_exists( $name, $builderValues['vars'] ) ) {
@ -1214,6 +1428,13 @@ class AbuseFilterParser {
$this->mVars->setVar( $name, $value );
}
/**
* @param $code
* @param $offset
* @return array
* @throws AFPException
* @throws AFPUserVisibleException
*/
static function nextToken( $code, $offset ) {
$tok = '';
@ -1394,7 +1615,7 @@ class AbuseFilterParser {
return array(
$float
? doubleval( $num )
? floatval( $num )
: intval( $num ),
$float
? AFPToken::TFloat
@ -1426,6 +1647,12 @@ class AbuseFilterParser {
}
// Built-in functions
/**
* @param $args
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function funcLc( $args ) {
global $wgContLang;
if ( count( $args ) < 1 ) {
@ -1439,6 +1666,11 @@ class AbuseFilterParser {
return new AFPData( AFPData::DString, $wgContLang->lc( $s ) );
}
/**
* @param $args
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function funcLen( $args ) {
if ( count( $args ) < 1 ) {
throw new AFPUserVisibleException(
@ -1451,6 +1683,11 @@ class AbuseFilterParser {
return new AFPData( AFPData::DInt, mb_strlen( $s, 'utf-8' ) );
}
/**
* @param $args
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function funcSimpleNorm( $args ) {
if ( count( $args ) < 1 ) {
throw new AFPUserVisibleException(
@ -1466,6 +1703,11 @@ class AbuseFilterParser {
return new AFPData( AFPData::DString, $s );
}
/**
* @param $args
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function funcSpecialRatio( $args ) {
if ( count( $args ) < 1 ) {
throw new AFPUserVisibleException(
@ -1487,6 +1729,11 @@ class AbuseFilterParser {
return new AFPData( AFPData::DFloat, $val );
}
/**
* @param $args
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function funcCount( $args ) {
if ( count( $args ) < 1 ) {
throw new AFPUserVisibleException(
@ -1517,6 +1764,12 @@ class AbuseFilterParser {
return new AFPData( AFPData::DInt, $count );
}
/**
* @param $args
* @return AFPData
* @throws AFPUserVisibleException
* @throws Exception
*/
protected function funcRCount( $args ) {
if ( count( $args ) < 1 ) {
throw new AFPUserVisibleException(
@ -1552,6 +1805,11 @@ class AbuseFilterParser {
return new AFPData( AFPData::DInt, $count );
}
/**
* @param $args
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function funcIPInRange( $args ) {
if ( count( $args ) < 2 ) {
throw new AFPUserVisibleException(
@ -1569,6 +1827,11 @@ class AbuseFilterParser {
return new AFPData( AFPData::DBool, $result );
}
/**
* @param $args
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function funcCCNorm( $args ) {
if ( count( $args ) < 1 ) {
throw new AFPUserVisibleException(
@ -1585,6 +1848,11 @@ class AbuseFilterParser {
return new AFPData( AFPData::DString, $s );
}
/**
* @param $args
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function funcContainsAny( $args ) {
if ( count( $args ) < 2 ) {
throw new AFPUserVisibleException(
@ -1621,6 +1889,10 @@ class AbuseFilterParser {
return new AFPData( AFPData::DBool, $ok );
}
/**
* @param $s
* @return mixed
*/
protected function ccnorm( $s ) {
static $equivset = null;
static $replacementArray = null;
@ -1634,20 +1906,35 @@ class AbuseFilterParser {
return $replacementArray->replace( $s );
}
/**
* @param $s string
* @return array|string
*/
protected function rmspecials( $s ) {
$s = preg_replace( '/[^\p{L}\p{N}]/u', '', $s );
return $s;
return preg_replace( '/[^\p{L}\p{N}]/u', '', $s );
}
/**
* @param $s string
* @return array|string
*/
protected function rmdoubles( $s ) {
return preg_replace( '/(.)\1+/us', '\1', $s );
}
/**
* @param $s string
* @return array|string
*/
protected function rmwhitespace( $s ) {
return preg_replace( '/\s+/u', '', $s );
}
/**
* @param $args array
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function funcRMSpecials( $args ) {
if ( count( $args ) < 1 ) {
throw new AFPUserVisibleException(
@ -1663,6 +1950,11 @@ class AbuseFilterParser {
return new AFPData( AFPData::DString, $s );
}
/**
* @param $args array
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function funcRMWhitespace( $args ) {
if ( count( $args ) < 1 ) {
throw new AFPUserVisibleException(
@ -1678,6 +1970,11 @@ class AbuseFilterParser {
return new AFPData( AFPData::DString, $s );
}
/**
* @param $args array
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function funcRMDoubles( $args ) {
if ( count( $args ) < 1 ) {
throw new AFPUserVisibleException(
@ -1693,6 +1990,11 @@ class AbuseFilterParser {
return new AFPData( AFPData::DString, $s );
}
/**
* @param $args array
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function funcNorm( $args ) {
if ( count( $args ) < 1 ) {
throw new AFPUserVisibleException(
@ -1711,6 +2013,11 @@ class AbuseFilterParser {
return new AFPData( AFPData::DString, $s );
}
/**
* @param $args array
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function funcSubstr( $args ) {
if ( count( $args ) < 2 ) {
throw new AFPUserVisibleException(
@ -1734,6 +2041,11 @@ class AbuseFilterParser {
return new AFPData( AFPData::DString, $result );
}
/**
* @param $args array
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function funcStrPos( $args ) {
if ( count( $args ) < 2 ) {
throw new AFPUserVisibleException(
@ -1760,6 +2072,11 @@ class AbuseFilterParser {
return new AFPData( AFPData::DInt, $result );
}
/**
* @param $args array
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function funcStrReplace( $args ) {
if ( count( $args ) < 3 ) {
throw new AFPUserVisibleException(
@ -1776,6 +2093,11 @@ class AbuseFilterParser {
return new AFPData( AFPData::DString, str_replace( $search, $replace, $subject ) );
}
/**
* @param $args array
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function funcStrRegexEscape( $args ) {
if ( count( $args ) < 1 ) {
throw new AFPUserVisibleException( 'notenoughargs', $this->mCur->pos,
@ -1788,6 +2110,11 @@ class AbuseFilterParser {
return new AFPData( AFPData::DString, preg_quote( $string ) );
}
/**
* @param $args array
* @return mixed
* @throws AFPUserVisibleException
*/
protected function funcSetVar( $args ) {
if ( count( $args ) < 2 ) {
throw new AFPUserVisibleException(
@ -1805,6 +2132,11 @@ class AbuseFilterParser {
return $value;
}
/**
* @param $args array
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function castString( $args ) {
if ( count( $args ) < 1 ) {
throw new AFPUserVisibleException( 'noparams', $this->mCur->pos, array( __METHOD__ ) );
@ -1814,6 +2146,11 @@ class AbuseFilterParser {
return AFPData::castTypes( $val, AFPData::DString );
}
/**
* @param $args array
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function castInt( $args ) {
if ( count( $args ) < 1 ) {
throw new AFPUserVisibleException( 'noparams', $this->mCur->pos, array( __METHOD__ ) );
@ -1823,6 +2160,11 @@ class AbuseFilterParser {
return AFPData::castTypes( $val, AFPData::DInt );
}
/**
* @param $args array
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function castFloat( $args ) {
if ( count( $args ) < 1 ) {
throw new AFPUserVisibleException( 'noparams', $this->mCur->pos, array( __METHOD__ ) );
@ -1832,6 +2174,11 @@ class AbuseFilterParser {
return AFPData::castTypes( $val, AFPData::DFloat );
}
/**
* @param $args array
* @return AFPData
* @throws AFPUserVisibleException
*/
protected function castBool( $args ) {
if ( count( $args ) < 1 ) {
throw new AFPUserVisibleException( 'noparams', $this->mCur->pos, array( __METHOD__ ) );

View file

@ -3,6 +3,10 @@ class AbuseFilterVariableHolder {
var $mVars = array();
static $varBlacklist = array( 'context' );
/**
* @param $variable
* @param $datum
*/
function setVar( $variable, $datum ) {
$variable = strtolower( $variable );
if ( !( $datum instanceof AFPData || $datum instanceof AFComputedVariable ) ) {
@ -12,11 +16,20 @@ class AbuseFilterVariableHolder {
$this->mVars[$variable] = $datum;
}
/**
* @param $variable
* @param $method
* @param $parameters
*/
function setLazyLoadVar( $variable, $method, $parameters ) {
$placeholder = new AFComputedVariable( $method, $parameters );
$this->setVar( $variable, $placeholder );
}
/**
* @param $variable
* @return AFPData
*/
function getVar( $variable ) {
$variable = strtolower( $variable );
if ( isset( $this->mVars[$variable] ) ) {
@ -32,6 +45,9 @@ class AbuseFilterVariableHolder {
}
}
/**
* @return AbuseFilterVariableHolder
*/
static function merge() {
$newHolder = new AbuseFilterVariableHolder;
@ -42,6 +58,10 @@ class AbuseFilterVariableHolder {
return $newHolder;
}
/**
* @param $addHolder
* @throws MWException
*/
function addHolder( $addHolder ) {
if ( !is_object( $addHolder ) ) {
throw new MWException( 'Invalid argument to AbuseFilterVariableHolder::addHolder' );
@ -54,6 +74,9 @@ class AbuseFilterVariableHolder {
$this->setVar( 'context', 'stored' );
}
/**
* @return array
*/
function exportAllVars() {
$allVarNames = array_keys( $this->mVars );
$exported = array();
@ -67,6 +90,10 @@ class AbuseFilterVariableHolder {
return $exported;
}
/**
* @param $var
* @return bool
*/
function varIsSet( $var ) {
return array_key_exists( $var, $this->mVars );
}
@ -102,6 +129,10 @@ class AFComputedVariable {
static $userCache = array();
static $articleCache = array();
/**
* @param $method
* @param $parameters
*/
function __construct( $method, $parameters ) {
$this->mMethod = $method;
$this->mParameters = $parameters;
@ -119,7 +150,7 @@ class AFComputedVariable {
function parseNonEditWikitext( $wikitext, $article ) {
static $cache = array();
$cacheKey = md5( $wikitext ) . ':' . $article->mTitle->getPrefixedText();
$cacheKey = md5( $wikitext ) . ':' . $article->getTitle()->getPrefixedText();
if ( isset( $cache[$cacheKey] ) ) {
return $cache[$cacheKey];
@ -135,6 +166,10 @@ class AFComputedVariable {
return $edit;
}
/**
* @param $username string
* @return User
*/
static function userObjectFromName( $username ) {
if ( isset( self::$userCache[$username] ) ) {
return self::$userCache[$username];
@ -160,6 +195,11 @@ class AFComputedVariable {
return $user;
}
/**
* @param $namespace
* @param $title Title
* @return Article
*/
static function articleFromTitle( $namespace, $title ) {
if ( isset( self::$articleCache["$namespace:$title"] ) ) {
return self::$articleCache["$namespace:$title"];
@ -177,6 +217,10 @@ class AFComputedVariable {
return self::$articleCache["$namespace:$title"];
}
/**
* @param $article Article
* @return array
*/
static function getLinksFromDB( $article ) {
// Stolen from ConfirmEdit
$id = $article->getId();
@ -198,6 +242,12 @@ class AFComputedVariable {
return $links;
}
/**
* @param $vars AbuseFilterVariableHolder
* @return AFPData|array|int|mixed|null|string
* @throws MWException
* @throws AFPException
*/
function compute( $vars ) {
$parameters = $this->mParameters;
$result = null;