Index: trunk/extensions/RegexFunctions/RegexFunctions.i18n.php |
— | — | @@ -1,6 +1,6 @@ |
2 | 2 | <?php |
3 | 3 | /** |
4 | | - * Internationalisation file for extension RegexFunctions. |
| 4 | + * Internationalisation file for RegexFunctions extension. |
5 | 5 | * |
6 | 6 | * @file |
7 | 7 | * @ingroup Extensions |
— | — | @@ -8,6 +8,7 @@ |
9 | 9 | |
10 | 10 | $messages = array(); |
11 | 11 | |
| 12 | +/** English */ |
12 | 13 | $messages['en'] = array( |
13 | 14 | 'regexfunctions-desc' => 'Regular expression parser functions', |
14 | 15 | ); |
— | — | @@ -100,7 +101,7 @@ |
101 | 102 | * @author Vililikku |
102 | 103 | */ |
103 | 104 | $messages['fi'] = array( |
104 | | - 'regexfunctions-desc' => 'Säännöllisten lausekkeiden jäsennysfunktioita.', |
| 105 | + 'regexfunctions-desc' => 'Säännöllisten lausekkeiden jäsennysfunktioita', |
105 | 106 | ); |
106 | 107 | |
107 | 108 | /** French (Français) |
Index: trunk/extensions/RegexFunctions/RegexFunctions.php |
— | — | @@ -1,7 +1,13 @@ |
2 | 2 | <?php |
3 | | -/* |
4 | | - * RegexFunctions extension by Ryan Schmidt |
5 | | - * Regular Expression parser functions |
| 3 | +/** |
| 4 | + * RegexFunctions extension -- Regular Expression parser functions |
| 5 | + * |
| 6 | + * @file |
| 7 | + * @ingroup Extensions |
| 8 | + * @author Ryan Schmidt |
| 9 | + * @version 1.4.1 |
| 10 | + * @license http://en.wikipedia.org/wiki/Public_domain Public domain |
| 11 | + * @link http://www.mediawiki.org/wiki/Extension:RegexFunctions Documentation |
6 | 12 | */ |
7 | 13 | |
8 | 14 | if( !defined( 'MEDIAWIKI' ) ) { |
— | — | @@ -9,42 +15,45 @@ |
10 | 16 | die( 1 ); |
11 | 17 | } |
12 | 18 | |
| 19 | +// Extension credits that will show up on Special:Version |
13 | 20 | $wgExtensionCredits['parserhook'][] = array( |
14 | | - 'path' => __FILE__, |
15 | | - 'name' => 'RegexFunctions', |
16 | | - 'author' => 'Ryan Schmidt', |
17 | | - 'url' => 'http://www.mediawiki.org/wiki/Extension:RegexFunctions', |
18 | | - 'version' => '1.4.1', |
| 21 | + 'path' => __FILE__, |
| 22 | + 'name' => 'RegexFunctions', |
| 23 | + 'author' => 'Ryan Schmidt', |
| 24 | + 'version' => '1.4.1', |
19 | 25 | 'descriptionmsg' => 'regexfunctions-desc', |
| 26 | + 'url' => 'http://www.mediawiki.org/wiki/Extension:RegexFunctions', |
20 | 27 | ); |
21 | 28 | |
22 | | -$dir = dirname(__FILE__) . '/'; |
| 29 | +$dir = dirname( __FILE__ ) . '/'; |
23 | 30 | $wgExtensionMessagesFiles['RegexFunctions'] = $dir . 'RegexFunctions.i18n.php'; |
24 | 31 | $wgExtensionMessagesFiles['RegexFunctionsMagic'] = $dir . 'RegexFunctions.i18n.magic.php'; |
25 | 32 | |
26 | 33 | $wgHooks['ParserFirstCallInit'][] = 'ExtRegexFunctions::onParserFirstCallInit'; |
27 | 34 | $wgHooks['ParserClearState'][] = 'ExtRegexFunctions::onParserClearState'; |
28 | 35 | |
29 | | -//default globals |
30 | | -//how many functions are allowed in a single page? Keep this at least above 3 for usability |
| 36 | +// default globals |
| 37 | +// how many functions are allowed in a single page? Keep this at least above 3 for usability |
31 | 38 | $wgRegexFunctionsPerPage = 10; |
32 | | -//should we allow modifiers in the functions, e.g. the /i modifier for case-insensitive? |
33 | | -//This does NOT enable the /e modifier for preg_replace, see the next variable for that |
| 39 | +// should we allow modifiers in the functions, e.g. the /i modifier for case-insensitive? |
| 40 | +// This does NOT enable the /e modifier for preg_replace, see the next variable for that |
34 | 41 | $wgRegexFunctionsAllowModifiers = true; |
35 | | -//should we allow the /e modifier in preg_replace? Requires AllowModifiers to be true. |
36 | | -//Don't enable this unless you trust every single editor on your wiki, as it may open up potential XSS vectors |
| 42 | +// should we allow the /e modifier in preg_replace? Requires AllowModifiers to be true. |
| 43 | +// Don't enable this unless you trust every single editor on your wiki, as it may open up potential XSS vectors |
37 | 44 | $wgRegexFunctionsAllowE = false; |
38 | | -//should we allow internal options to be set (e.g. (?opts) or (?opts:some regex)) |
| 45 | +// should we allow internal options to be set (e.g. (?opts) or (?opts:some regex)) |
39 | 46 | $wgRegexFunctionsAllowOptions = true; |
40 | | -//limit for rsplit and rreplace functions. -1 is unlimited |
| 47 | +// limit for rsplit and rreplace functions. -1 is unlimited |
41 | 48 | $wgRegexFunctionsLimit = -1; |
42 | | -//array of functions to disable, aka these functions cannot be used :) |
| 49 | +// array of functions to disable, aka these functions cannot be used :) |
43 | 50 | $wgRegexFunctionsDisable = array(); |
44 | 51 | |
45 | 52 | class ExtRegexFunctions { |
46 | 53 | private static $num = 0; |
47 | | - private static $modifiers = array('i', 'm', 's', 'x', 'A', 'D', 'S', 'U', 'X', 'J', 'u', 'e'); |
48 | | - private static $options = array('i', 'm', 's', 'x', 'U', 'X', 'J'); |
| 54 | + private static $modifiers = array( |
| 55 | + 'i', 'm', 's', 'x', 'A', 'D', 'S', 'U', 'X', 'J', 'u', 'e' |
| 56 | + ); |
| 57 | + private static $options = array( 'i', 'm', 's', 'x', 'U', 'X', 'J' ); |
49 | 58 | |
50 | 59 | public static function onParserFirstCallInit( $parser ) { |
51 | 60 | $parser->setFunctionHook( 'rmatch', array( __CLASS__, 'rmatch' ) ); |
— | — | @@ -58,94 +67,152 @@ |
59 | 68 | return true; |
60 | 69 | } |
61 | 70 | |
62 | | - public static function rmatch ( &$parser, $string = '', $pattern = '', $return = '', $notfound = '', $offset = 0 ) { |
| 71 | + public static function rmatch( &$parser, $string = '', $pattern = '', $return = '', $notfound = '', $offset = 0 ) { |
63 | 72 | global $wgRegexFunctionsPerPage, $wgRegexFunctionsAllowModifiers, $wgRegexFunctionsDisable; |
64 | | - if(in_array('rmatch', $wgRegexFunctionsDisable)) |
| 73 | + if( in_array( 'rmatch', $wgRegexFunctionsDisable ) ) { |
65 | 74 | return; |
| 75 | + } |
66 | 76 | self::$num++; |
67 | | - if( self::$num > $wgRegexFunctionsPerPage) |
| 77 | + if( self::$num > $wgRegexFunctionsPerPage ) { |
68 | 78 | return; |
69 | | - $pattern = self::sanitize($pattern, $wgRegexFunctionsAllowModifiers, false); |
70 | | - $num = preg_match( $pattern, $string, $matches, PREG_OFFSET_CAPTURE, (int) $offset ); |
71 | | - if($num === false) |
| 79 | + } |
| 80 | + $pattern = self::sanitize( |
| 81 | + $pattern, |
| 82 | + $wgRegexFunctionsAllowModifiers, |
| 83 | + false |
| 84 | + ); |
| 85 | + $num = preg_match( |
| 86 | + $pattern, $string, $matches, PREG_OFFSET_CAPTURE, (int) $offset |
| 87 | + ); |
| 88 | + if( $num === false ) { |
72 | 89 | return; |
73 | | - if($num === 0) |
| 90 | + } |
| 91 | + if( $num === 0 ) { |
74 | 92 | return $notfound; |
75 | | - //change all backslashes to $ |
76 | | - $return = str_replace('\\', '%$', $return); |
77 | | - $return = preg_replace('/%?\$%?\$([0-9]+)/e', 'array_key_exists($1, $matches) ? $matches[$1][1] : \'\'', $return); |
78 | | - $return = preg_replace('/%?\$%?\$\{([0-9]+)\}/e', 'array_key_exists($1, $matches) ? $matches[$1][1] : \'\'', $return); |
79 | | - $return = preg_replace('/%?\$([0-9]+)/e', 'array_key_exists($1, $matches) ? $matches[$1][0] : \'\'', $return); |
80 | | - $return = preg_replace('/%?\$\{([0-9]+)\}/e', 'array_key_exists($1, $matches) ? $matches[$1][0] : \'\'', $return); |
81 | | - $return = str_replace('%$', '\\', $return); |
| 93 | + } |
| 94 | + // change all backslashes to $ |
| 95 | + $return = str_replace( '\\', '%$', $return ); |
| 96 | + $return = preg_replace( |
| 97 | + '/%?\$%?\$([0-9]+)/e', |
| 98 | + 'array_key_exists($1, $matches) ? $matches[$1][1] : \'\'', |
| 99 | + $return |
| 100 | + ); |
| 101 | + $return = preg_replace( |
| 102 | + '/%?\$%?\$\{([0-9]+)\}/e', |
| 103 | + 'array_key_exists($1, $matches) ? $matches[$1][1] : \'\'', |
| 104 | + $return |
| 105 | + ); |
| 106 | + $return = preg_replace( |
| 107 | + '/%?\$([0-9]+)/e', |
| 108 | + 'array_key_exists($1, $matches) ? $matches[$1][0] : \'\'', |
| 109 | + $return |
| 110 | + ); |
| 111 | + $return = preg_replace( |
| 112 | + '/%?\$\{([0-9]+)\}/e', |
| 113 | + 'array_key_exists($1, $matches) ? $matches[$1][0] : \'\'', |
| 114 | + $return |
| 115 | + ); |
| 116 | + $return = str_replace( '%$', '\\', $return ); |
82 | 117 | return $return; |
83 | 118 | } |
84 | 119 | |
85 | | - public static function rsplit ( &$parser, $string = '', $pattern = '', $piece = 0 ) { |
| 120 | + public static function rsplit( &$parser, $string = '', $pattern = '', $piece = 0 ) { |
86 | 121 | global $wgRegexFunctionsPerPage, $wgRegexFunctionsAllowModifiers, $wgRegexFunctionsLimit, $wgRegexFunctionsDisable; |
87 | | - if(in_array('rsplit', $wgRegexFunctionsDisable)) |
| 122 | + if( in_array( 'rsplit', $wgRegexFunctionsDisable ) ) { |
88 | 123 | return; |
| 124 | + } |
89 | 125 | self::$num++; |
90 | | - if(self::$num > $wgRegexFunctionsPerPage) |
| 126 | + if( self::$num > $wgRegexFunctionsPerPage ) { |
91 | 127 | return; |
92 | | - $pattern = self::sanitize($pattern, $wgRegexFunctionsAllowModifiers, false); |
| 128 | + } |
| 129 | + $pattern = self::sanitize( |
| 130 | + $pattern, |
| 131 | + $wgRegexFunctionsAllowModifiers, |
| 132 | + false |
| 133 | + ); |
93 | 134 | $res = preg_split( $pattern, $string, $wgRegexFunctionsLimit ); |
94 | 135 | $p = (int) $piece; |
95 | | - //allow negative pieces to work from the end of the array |
96 | | - if($p < 0) |
97 | | - $p = $p + count($res); |
98 | | - //sanitation for pieces that don't exist |
99 | | - if($p < 0) |
| 136 | + // allow negative pieces to work from the end of the array |
| 137 | + if( $p < 0 ) { |
| 138 | + $p = $p + count( $res ); |
| 139 | + } |
| 140 | + // sanitation for pieces that don't exist |
| 141 | + if( $p < 0 ) { |
100 | 142 | $p = 0; |
101 | | - if($p >= count($res)) |
102 | | - $p = count($res) - 1; |
| 143 | + } |
| 144 | + if( $p >= count( $res ) ) { |
| 145 | + $p = count( $res ) - 1; |
| 146 | + } |
103 | 147 | return $res[$p]; |
104 | 148 | } |
105 | 149 | |
106 | | - public static function rreplace ( &$parser, $string = '', $pattern = '', &$replace = '' ) { |
| 150 | + public static function rreplace( &$parser, $string = '', $pattern = '', &$replace = '' ) { |
107 | 151 | global $wgRegexFunctionsPerPage, $wgRegexFunctionsAllowModifiers, $wgRegexFunctionsAllowE, $wgRegexFunctionsLimit, $wgRegexFunctionsDisable; |
108 | | - if(in_array('rreplace', $wgRegexFunctionsDisable)) |
| 152 | + if( in_array( 'rreplace', $wgRegexFunctionsDisable ) ) { |
109 | 153 | return; |
| 154 | + } |
110 | 155 | self::$num++; |
111 | | - if(self::$num > $wgRegexFunctionsPerPage) |
| 156 | + if( self::$num > $wgRegexFunctionsPerPage ) { |
112 | 157 | return; |
113 | | - $pattern = self::sanitize($pattern, $wgRegexFunctionsAllowModifiers, $wgRegexFunctionsAllowE); |
114 | | - $res = preg_replace($pattern, $replace, $string, $wgRegexFunctionsLimit); |
| 158 | + } |
| 159 | + $pattern = self::sanitize( |
| 160 | + $pattern, |
| 161 | + $wgRegexFunctionsAllowModifiers, |
| 162 | + $wgRegexFunctionsAllowE |
| 163 | + ); |
| 164 | + $res = preg_replace( |
| 165 | + $pattern, |
| 166 | + $replace, |
| 167 | + $string, |
| 168 | + $wgRegexFunctionsLimit |
| 169 | + ); |
115 | 170 | return $res; |
116 | 171 | } |
117 | 172 | |
118 | | - //santizes a regex pattern |
119 | | - private static function sanitize($pattern, $m = false, $e = false) { |
120 | | - if(preg_match('/^\/(.*)([^\\\\])\/(.*?)$/', $pattern, $matches)) { |
121 | | - $pat = preg_replace('/([^\\\\])?\(\?(.*\:)?(.*)\)/Ue', '\'$1(?\' . self::cleanupInternal(\'$2\') . \'$3)\'', $matches[1] . $matches[2]); |
| 173 | + // santizes a regex pattern |
| 174 | + private static function sanitize( $pattern, $m = false, $e = false ) { |
| 175 | + if( preg_match( '/^\/(.*)([^\\\\])\/(.*?)$/', $pattern, $matches ) ) { |
| 176 | + $pat = preg_replace( |
| 177 | + '/([^\\\\])?\(\?(.*\:)?(.*)\)/Ue', |
| 178 | + '\'$1(?\' . self::cleanupInternal(\'$2\') . \'$3)\'', |
| 179 | + $matches[1] . $matches[2] |
| 180 | + ); |
122 | 181 | $ret = '/' . $pat . '/'; |
123 | | - if($m) { |
| 182 | + if( $m ) { |
124 | 183 | $mod = ''; |
125 | | - foreach(self::$modifiers as $val) { |
126 | | - if(strpos($matches[3], $val) !== false) |
| 184 | + foreach( self::$modifiers as $val ) { |
| 185 | + if( strpos( $matches[3], $val ) !== false ) { |
127 | 186 | $mod .= $val; |
| 187 | + } |
128 | 188 | } |
129 | | - if(!$e) |
130 | | - $mod = str_replace('e', '', $mod); |
| 189 | + if( !$e ) { |
| 190 | + $mod = str_replace( 'e', '', $mod ); |
| 191 | + } |
131 | 192 | $ret .= $mod; |
132 | 193 | } |
133 | 194 | } else { |
134 | | - $pat = preg_replace('/([^\\\\])?\(\?(.*\:)?(.*)\)/Ue', '\'$1(?\' . self::cleanupInternal(\'$2\') . \'$3)\'', $pattern); |
135 | | - $pat = preg_replace('!([^\\\\])/!', '$1\\/', $pat); |
| 195 | + $pat = preg_replace( |
| 196 | + '/([^\\\\])?\(\?(.*\:)?(.*)\)/Ue', |
| 197 | + '\'$1(?\' . self::cleanupInternal(\'$2\') . \'$3)\'', |
| 198 | + $pattern |
| 199 | + ); |
| 200 | + $pat = preg_replace( '!([^\\\\])/!', '$1\\/', $pat ); |
136 | 201 | $ret = '/' . $pat . '/'; |
137 | 202 | } |
138 | 203 | return $ret; |
139 | 204 | } |
140 | 205 | |
141 | | - //cleans up internal options, making sure they are valid |
142 | | - private static function cleanupInternal($str) { |
| 206 | + // cleans up internal options, making sure they are valid |
| 207 | + private static function cleanupInternal( $str ) { |
143 | 208 | global $wgRegexFunctionsAllowOptions; |
144 | 209 | $ret = ''; |
145 | | - if(!$wgRegexFunctionsAllowOptions) |
| 210 | + if( !$wgRegexFunctionsAllowOptions ) { |
146 | 211 | return ''; |
147 | | - foreach(self::$options as $opt) { |
148 | | - if(strpos($str, $opt) !== false) |
| 212 | + } |
| 213 | + foreach( self::$options as $opt ) { |
| 214 | + if( strpos( $str, $opt ) !== false ) { |
149 | 215 | $ret .= $opt; |
| 216 | + } |
150 | 217 | } |
151 | 218 | return $ret; |
152 | 219 | } |