MediaWiki REL1_39
StripState.php
Go to the documentation of this file.
1<?php
30 protected $data;
31 protected $regex;
32
33 protected $parser;
34
36 protected $depth = 0;
37 protected $highestDepth = 0;
38 protected $expandSize = 0;
39
40 protected $depthLimit = 20;
41 protected $sizeLimit = 5000000;
42
49 public function __construct( Parser $parser = null, $options = [] ) {
50 $this->data = [
51 'nowiki' => [],
52 'general' => []
53 ];
54 $this->regex = '/' . Parser::MARKER_PREFIX . "([^\x7f<>&'\"]+)" . Parser::MARKER_SUFFIX . '/';
55 $this->circularRefGuard = [];
56 $this->parser = $parser;
57
58 if ( isset( $options['depthLimit'] ) ) {
59 $this->depthLimit = $options['depthLimit'];
60 }
61 if ( isset( $options['sizeLimit'] ) ) {
62 $this->sizeLimit = $options['sizeLimit'];
63 }
64 }
65
71 public function addNoWiki( $marker, $value ) {
72 $this->addItem( 'nowiki', $marker, $value );
73 }
74
79 public function addGeneral( $marker, $value ) {
80 $this->addItem( 'general', $marker, $value );
81 }
82
89 protected function addItem( $type, $marker, $value ) {
90 if ( !preg_match( $this->regex, $marker, $m ) ) {
91 throw new MWException( "Invalid marker: $marker" );
92 }
93
94 $this->data[$type][$m[1]] = $value;
95 }
96
101 public function unstripGeneral( $text ) {
102 return $this->unstripType( 'general', $text );
103 }
104
109 public function unstripNoWiki( $text ) {
110 return $this->unstripType( 'nowiki', $text );
111 }
112
118 public function replaceNoWikis( string $text, callable $callback ): string {
119 // Shortcut
120 if ( !count( $this->data['nowiki'] ) ) {
121 return $text;
122 }
123
124 $callback = function ( $m ) use ( $callback ) {
125 $marker = $m[1];
126 if ( isset( $this->data['nowiki'][$marker] ) ) {
127 $value = $this->data['nowiki'][$marker];
128 if ( $value instanceof Closure ) {
129 $value = $value();
130 }
131
132 $this->expandSize += strlen( $value );
133 if ( $this->expandSize > $this->sizeLimit ) {
134 return $this->getLimitationWarning( 'unstrip-size', $this->sizeLimit );
135 }
136
137 return call_user_func( $callback, $value );
138 } else {
139 return $m[0];
140 }
141 };
142
143 return preg_replace_callback( $this->regex, $callback, $text );
144 }
145
150 public function unstripBoth( $text ) {
151 $text = $this->unstripType( 'general', $text );
152 $text = $this->unstripType( 'nowiki', $text );
153 return $text;
154 }
155
161 protected function unstripType( $type, $text ) {
162 // Shortcut
163 if ( !count( $this->data[$type] ) ) {
164 return $text;
165 }
166
167 $callback = function ( $m ) use ( $type ) {
168 $marker = $m[1];
169 if ( isset( $this->data[$type][$marker] ) ) {
170 if ( isset( $this->circularRefGuard[$marker] ) ) {
171 return $this->getWarning( 'parser-unstrip-loop-warning' );
172 }
173
174 if ( $this->depth > $this->highestDepth ) {
175 $this->highestDepth = $this->depth;
176 }
177 if ( $this->depth >= $this->depthLimit ) {
178 return $this->getLimitationWarning( 'unstrip-depth', $this->depthLimit );
179 }
180
181 $value = $this->data[$type][$marker];
182 if ( $value instanceof Closure ) {
183 $value = $value();
184 }
185
186 $this->expandSize += strlen( $value );
187 if ( $this->expandSize > $this->sizeLimit ) {
188 return $this->getLimitationWarning( 'unstrip-size', $this->sizeLimit );
189 }
190
191 $this->circularRefGuard[$marker] = true;
192 $this->depth++;
193 $ret = $this->unstripType( $type, $value );
194 $this->depth--;
195 unset( $this->circularRefGuard[$marker] );
196
197 return $ret;
198 } else {
199 return $m[0];
200 }
201 };
202
203 $text = preg_replace_callback( $this->regex, $callback, $text );
204 return $text;
205 }
206
214 private function getLimitationWarning( $type, $max = '' ) {
215 if ( $this->parser ) {
216 $this->parser->limitationWarn( $type, $max );
217 }
218 return $this->getWarning( "$type-warning", $max );
219 }
220
228 private function getWarning( $message, $max = '' ) {
229 return '<span class="error">' .
230 wfMessage( $message )
231 ->numParams( $max )->inContentLanguage()->text() .
232 '</span>';
233 }
234
241 public function getLimitReport() {
242 return [
243 [ 'limitreport-unstrip-depth',
244 [
245 $this->highestDepth,
246 $this->depthLimit
247 ],
248 ],
249 [ 'limitreport-unstrip-size',
250 [
251 $this->expandSize,
252 $this->sizeLimit
253 ],
254 ]
255 ];
256 }
257
264 public function killMarkers( $text ) {
265 return preg_replace( $this->regex, '', $text );
266 }
267}
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
if(!defined('MW_SETUP_CALLBACK'))
The persistent session ID (if any) loaded at startup.
Definition WebStart.php:82
MediaWiki exception.
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition Parser.php:96
const MARKER_PREFIX
Definition Parser.php:155
unstripBoth( $text)
unstripGeneral( $text)
addNoWiki( $marker, $value)
Add a nowiki strip item.
getLimitReport()
Get an array of parameters to pass to ParserOutput::setLimitReportData()
unstripType( $type, $text)
replaceNoWikis(string $text, callable $callback)
addGeneral( $marker, $value)
killMarkers( $text)
Remove any strip markers found in the given text.
addItem( $type, $marker, $value)
__construct(Parser $parser=null, $options=[])
unstripNoWiki( $text)