Revision: 46301
Author:   werdna
Date:     2009-01-26 23:32:46 +0000 (Mon, 26 Jan 2009)

Log Message:
-----------
Localise Abuse Filter exceptions.

Modified Paths:
--------------
    trunk/extensions/AbuseFilter/AbuseFilter.class.php
    trunk/extensions/AbuseFilter/AbuseFilter.i18n.php
    trunk/extensions/AbuseFilter/AbuseFilter.parser.php
    trunk/extensions/AbuseFilter/edit.js

Modified: trunk/extensions/AbuseFilter/AbuseFilter.class.php
===================================================================
--- trunk/extensions/AbuseFilter/AbuseFilter.class.php  2009-01-26 23:28:15 UTC 
(rev 46300)
+++ trunk/extensions/AbuseFilter/AbuseFilter.class.php  2009-01-26 23:32:46 UTC 
(rev 46301)
@@ -31,6 +31,8 @@
        }
        
        public static function ajaxCheckSyntax( $filter ) {
+               wfLoadExtensionMessages( 'AbuseFilter' );
+               
                $result = self::checkSyntax( $filter );
                
                $ok = ($result === true);
@@ -38,7 +40,7 @@
                if ($ok) {
                        return "OK";
                } else {
-                       return "ERR: $result";
+                       return "ERR: ".json_encode( $result );
                }
        }
 

Modified: trunk/extensions/AbuseFilter/AbuseFilter.i18n.php
===================================================================
--- trunk/extensions/AbuseFilter/AbuseFilter.i18n.php   2009-01-26 23:28:15 UTC 
(rev 46300)
+++ trunk/extensions/AbuseFilter/AbuseFilter.i18n.php   2009-01-26 23:32:46 UTC 
(rev 46301)
@@ -254,6 +254,17 @@
        'abusefilter-history-select-legend' => 'Refine search',
        'abusefilter-history-select-user' => 'User:',
        'abusefilter-history-select-submit' => 'Refine',
+
+       // Exceptions
+       'abusefilter-exception-unexpectedatend' => 'Unexpected "$2" at end.',
+       'abusefilter-exception-expectednotfound' => 'Expected a $2 at character 
$1, not found.',
+       'abusefilter-exception-unrecognisedkeyword' => 'Unrecognised keyword $2 
at character $1.',
+       'abusefilter-exception-unexpectedtoken' => 'Unexpected token "$2" at 
character $1.',
+       'abusefilter-exception-unclosedstring' => 'Unclosed string starting at 
character $1.',
+       'abusefilter-exception-invalidoperator' => 'Invalid operator $2 at 
character $1.',
+       'abusefilter-exception-unrecognisedtoken' => 'Unrecognised token "$2" 
at character $1.',
+       'abusefilter-exception-noparams' => 'No parameters given to function 
"$2" at character $1.',
+       'abusefilter-exception-dividebyzero' => 'Illegal attempt to divide $2 
by zero.',
 );
 
 /** Message documentation (Message documentation)

Modified: trunk/extensions/AbuseFilter/AbuseFilter.parser.php
===================================================================
--- trunk/extensions/AbuseFilter/AbuseFilter.parser.php 2009-01-26 23:28:15 UTC 
(rev 46300)
+++ trunk/extensions/AbuseFilter/AbuseFilter.parser.php 2009-01-26 23:32:46 UTC 
(rev 46301)
@@ -182,7 +182,7 @@
                        return new AFPData( self::DBool, $a && $b );
                if( $op == '^' )
                        return new AFPData( self::DBool, $a xor $b );
-               throw new AFPException( "Invalid boolean operation: {$op}" );
+               throw new AFPException( "Invalid boolean operation: {$op}" ); 
// Should never happen.
        }
        
        public static function compareOp( $a, $b, $op ) {
@@ -204,7 +204,7 @@
                        return new AFPData( self::DBool, $a >= $b );
                if( $op == '<=' )
                        return new AFPData( self::DBool, $a <= $b );
-               throw new AFPException( "Invalid comprasion operation: {$op}" );
+               throw new AFPException( "Invalid comparison operation: {$op}" 
); // Should never happen
        }
        
        public static function mulRel( $a, $b, $op ) {  
@@ -221,7 +221,7 @@
                }
 
                if ($op != '*' && $b == 0) {
-                       throw new AFPException( "Illegal attempt to divide $a 
by 0." );
+                       throw new AFPUserVisibleException( 'dividebyzero', 0, 
array($a) );
                }
 
                $data = null;
@@ -232,7 +232,7 @@
                elseif( $op == '%' )
                        $data = $a % $b;
                else
-                       throw new AFPException( "Invalid multiplication-related 
operation: {$op}" );
+                       throw new AFPException( "Invalid multiplication-related 
operation: {$op}" ); // Should never happen
                        
                if ($type == self::DInt)
                        $data = intval($data);
@@ -272,6 +272,19 @@
 }
 
 class AFPException extends MWException {}
+
+// Exceptions that we might conceivably want to report to ordinary users
+// (i.e. exceptions that don't represent bugs in the extension itself)
+class AFPUserVisibleException extends AFPException {
+       function __construct( $exception_id, $position, $params) {
+               $msg = wfMsgExt( 'abusefilter-exception-'.$exception_id, 
array(), array_merge( array($position), $params ) );
+               parent::__construct( $msg );
+
+               $this->mExceptionID = $exception_id;
+               $this->mPosition = $position;
+               $this->mParams = $params;
+       }
+}
        
 class AbuseFilterParser {
        var $mParams, $mVars, $mCode, $mTokens, $mPos, $mCur;
@@ -319,8 +332,8 @@
        public function checkSyntax( $filter ) {
                try {
                        $this->parse($filter);
-               } catch (AFPException $excep) {
-                       return $excep->getMessage();
+               } catch (AFPUserVisibleException $excep) {
+                       return array($excep->getMessage(), $excep->mPosition);
                }
                return true;
        }
@@ -376,7 +389,7 @@
        protected function doLevelEntry( &$result ) {
                $this->doLevelSet( $result );
                if( $this->mCur->type != AFPToken::TNone ) {
-                       throw new AFPException( "Unexpected {$this->mCur->type} 
at char {$this->mCur->pos}" );
+                       throw new AFPUserVisibleException( 'unexpectedatend', 
$this->mCur->pos, array($this->mCur->type) );
                }
        }
        
@@ -390,13 +403,13 @@
                        $this->move();
                        $this->doLevelBoolOps( $result );
                        if( !($this->mCur->type == AFPToken::TKeyword && 
$this->mCur->value == 'then') )
-                               throw new AFPException( "Excepted \"then\" at 
char {$this->mCur->pos}" );
+                               throw new AFPUserVisibleException( 
'expectednotfound', $this->mCur->pos, array('then') );
                        $this->move();
                        $r1 = new AFPData();
                        $r2 = new AFPData();
                        $this->doLevelConditions( $r1 );
                        if( !($this->mCur->type == AFPToken::TKeyword && 
$this->mCur->value == 'else') )
-                               throw new AFPException( "Excepted \"else\" at 
char {$this->mCur->pos}" );
+                               throw new AFPUserVisibleException( 
'expectednotfound', $this->mCur->pos, array('else') );
                        $this->move();
                        $this->doLevelConditions( $r2 );
                        if( $result->toBool() ) {
@@ -405,7 +418,7 @@
                                $result = $r2;
                        }
                        if( !($this->mCur->type == AFPToken::TKeyword && 
$this->mCur->value == 'end') )
-                               throw new AFPException( "Excepted \"else\" at 
char {$this->mCur->pos}" );
+                               throw new AFPUserVisibleException( 
'expectednotfound', $this->mCur->pos, array('end') );
                        $this->move();
                } else {
                        $this->doLevelBoolOps( $result );
@@ -415,7 +428,7 @@
                                $r2 = new AFPData();
                                $this->doLevelConditions( $r1 );
                                if( !($this->mCur->type == AFPToken::TOp && 
$this->mCur->value == ':') )
-                                       throw new AFPException( "Excepted \":\" 
at char {$this->mCur->pos}" );
+                                       throw new AFPUserVisibleException( 
'expectednotfound', $this->mCur->pos, array(':') );
                                $this->move();
                                $this->doLevelConditions( $r2 );
                                if( $result->toBool() ) {
@@ -547,7 +560,7 @@
                        $this->move();
                        $this->doLevelSet( $result );
                        if( !($this->mCur->type == AFPToken::TBrace && 
$this->mCur->value == ')') )
-                               throw new AFPException( "Expected ) at char 
{$this->mCur->pos}" );
+                               throw new AFPUserVisibleException( 
'expectednotfound', $this->mCur->pos, array(')') );
                        $this->move();
                } else {
                        $this->doLevelFunction( $result );
@@ -560,7 +573,7 @@
                        $func = self::$mFunctions[$this->mCur->value];
                        $this->move();
                        if( $this->mCur->type != AFPToken::TBrace || 
$this->mCur->value != '(' )
-                               throw new AFPException( "Expected ( at char 
{$this->mCur->pos} (got a '{$this->mCur->value}')" );
+                               throw new AFPUserVisibleException( 
'expectednotfound', $this->mCur->pos, array('(') );
                        wfProfileIn( __METHOD__."-loadargs" );
                        $args = array();
                        do {
@@ -571,7 +584,7 @@
                        } while( $this->mCur->type == AFPToken::TComma );
                        
                        if( $this->mCur->type != AFPToken::TBrace || 
$this->mCur->value != ')' ) {
-                               throw new AFPException( "Expected ) at char 
{$this->mCur->pos}, instead I see {$this->mCur->value}, a {$this->mCur->type}" 
);
+                               throw new AFPUserVisibleException( 
'expectednotfound', $this->mCur->pos, array(')') );
                        }
                        wfProfileOut( __METHOD__."-loadargs" );
                        
@@ -627,13 +640,13 @@
                                elseif( $tok == "null" )
                                        $result = new AFPData();
                                else
-                                       throw new AFPException( "Unexpected 
{$this->mCur->type} at char {$this->mCur->pos}" );
+                                       throw new AFPUserVisibleException( 
'unrecognisedkeyword', $this->mCur->pos, array($tok) );
                                break;
                        case AFPToken::TBrace:
                        if( $this->mCur->value == ')' )
                                return;        // Handled at the entry level
                        default:
-                               throw new AFPException( "Unexpected 
{$this->mCur->type} at char {$this->mCur->pos}" );
+                               throw new AFPUserVisibleException( 
'unexpectedtoken', $this->mCur->pos, array($this->mCur->value) );
                }
                $this->move();
                wfProfileOut( __METHOD__ );
@@ -723,7 +736,7 @@
                                        $code = substr( $code, 1 );
                                }
                        }
-                       throw new AFPException( "Unclosed string begining at 
char $pos" );
+                       throw new AFPUserVisibleException( 'unclosedstring', 
$pos, array() );;
                }
                
                $bases = array( 'b' => 2, 'x' => 16, 'o' => 8 );
@@ -764,7 +777,7 @@
                                $code = substr( $code, 1 );
                        }
                        if( !in_array( $tok, self::$mOps ) )
-                       throw new AFPException( "Invalid operator: {$tok} (at 
char $pos)" );
+                       throw new AFPUserVisibleException( 'invalidoperator', 
$this->mCur->pos, array($tok) );
                        return array( $tok, AFPToken::TOp, $code, $pos );
                }
                
@@ -777,7 +790,7 @@
                        return array( $tok, $type, $code, $pos );
                }
                
-               throw new AFPException( "Unrecognized token \"{$code[0]}\" at 
char $pos" );
+               throw new AFPUserVisibleException( 'unrecognisedtoken', 
$this->mCur->pos, array($code[0]) );;
        }
        
        protected static function isDigitOrDot( $chr ) {
@@ -930,7 +943,7 @@
        
        protected function castString( $args ) {
                if ( count( $args ) < 1)
-                       throw new AFPException( "No params passed to 
".__METHOD__ );
+                       throw new AFPUserVisibleException( 'noparams', 
$this->mCur->pos, array(__METHOD__) );
                $val = $args[0];
                
                return new AFPData( AFPData::DString, $val->data );
@@ -938,7 +951,7 @@
        
        protected function castInt( $args ) {
                if ( count( $args ) < 1)
-                       throw new AFPException( "No params passed to 
".__METHOD__ );
+                       throw new AFPUserVisibleException( 'noparams', 
$this->mCur->pos, array(__METHOD__) );
                $val = $args[0];
                
                return new AFPData( AFPData::DInt, intval($val->data) );
@@ -946,7 +959,7 @@
 
        protected function castFloat( $args ) {
                if ( count( $args ) < 1)
-                       throw new AFPException( "No params passed to 
".__METHOD__ );
+                       throw new AFPUserVisibleException( 'noparams', 
$this->mCur->pos, array(__METHOD__) );
                $val = $args[0];
                
                return new AFPData( AFPData::DFloat, doubleval($val->data) );
@@ -954,7 +967,7 @@
        
        protected function castBool( $args ) {
                if ( count( $args ) < 1)
-                       throw new AFPException( "No params passed to 
".__METHOD__ );
+                       throw new AFPUserVisibleException( 'noparams', 
$this->mCur->pos, array(__METHOD__) );
                $val = $args[0];
                
                return new AFPData( AFPData::DBool, (bool)($val->data) );

Modified: trunk/extensions/AbuseFilter/edit.js
===================================================================
--- trunk/extensions/AbuseFilter/edit.js        2009-01-26 23:28:15 UTC (rev 
46300)
+++ trunk/extensions/AbuseFilter/edit.js        2009-01-26 23:32:46 UTC (rev 
46301)
@@ -18,26 +18,22 @@
                changeText( el, 'No syntax errors.' );
                el.syntaxOk = true;
        } else {
-               var error = response.substr(4);
-               changeText( el, 'Syntax error: '+error );
+               var errorData = eval(response.substr(4));
+               changeText( el, 'Syntax error: '+errorData[0] );
                el.syntaxOk = false;
 
-               var charRegex = /at char (\d+)/;
-               if ( charRegex.test( error ) ) {
-                       var charArray = charRegex.exec( error );
-                       var position = charArray[1];
-                       var textArea = document.getElementById( wgFilterBoxName 
);
+               var position = errorData[1];
+               var textArea = document.getElementById( wgFilterBoxName );
 
-                       textArea.focus();
-                       if (document.selection) {
-                               var sel = document.selection.createRange();
-                               sel.moveStart( 'character', 
-textArea.value.length );
-                               sel.moveStart( 'character', position );
-                               sel.select();
-                       } else if (textArea.selectionStart && 
textArea.selectionEnd) {
-                               textArea.selectionStart = position;
-                               textArea.selectionEnd = position;
-                       }
+               textArea.focus();
+               if (document.selection) {
+                       var sel = document.selection.createRange();
+                       sel.moveStart( 'character', -textArea.value.length );
+                       sel.moveStart( 'character', position );
+                       sel.select();
+               } else if (textArea.selectionStart && textArea.selectionEnd) {
+                       textArea.selectionStart = position;
+                       textArea.selectionEnd = position;
                }
        }
 }



_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to