MediaWiki  1.23.0
ConverterRule.php
Go to the documentation of this file.
1 <?php
28  public $mText; // original text in -{text}-
29  public $mConverter; // LanguageConverter object
30  public $mRuleDisplay = '';
31  public $mRuleTitle = false;
32  public $mRules = '';// string : the text of the rules
33  public $mRulesAction = 'none';
34  public $mFlags = array();
35  public $mVariantFlags = array();
36  public $mConvTable = array();
37  public $mBidtable = array();// array of the translation in each variant
38  public $mUnidtable = array();// array of the translation in each variant
39 
46  public function __construct( $text, $converter ) {
47  $this->mText = $text;
48  $this->mConverter = $converter;
49  }
50 
57  public function getTextInBidtable( $variants ) {
58  $variants = (array)$variants;
59  if ( !$variants ) {
60  return false;
61  }
62  foreach ( $variants as $variant ) {
63  if ( isset( $this->mBidtable[$variant] ) ) {
64  return $this->mBidtable[$variant];
65  }
66  }
67  return false;
68  }
69 
74  function parseFlags() {
75  $text = $this->mText;
76  $flags = array();
77  $variantFlags = array();
78 
79  $sepPos = strpos( $text, '|' );
80  if ( $sepPos !== false ) {
81  $validFlags = $this->mConverter->mFlags;
82  $f = StringUtils::explode( ';', substr( $text, 0, $sepPos ) );
83  foreach ( $f as $ff ) {
84  $ff = trim( $ff );
85  if ( isset( $validFlags[$ff] ) ) {
86  $flags[$validFlags[$ff]] = true;
87  }
88  }
89  $text = strval( substr( $text, $sepPos + 1 ) );
90  }
91 
92  if ( !$flags ) {
93  $flags['S'] = true;
94  } elseif ( isset( $flags['R'] ) ) {
95  $flags = array( 'R' => true );// remove other flags
96  } elseif ( isset( $flags['N'] ) ) {
97  $flags = array( 'N' => true );// remove other flags
98  } elseif ( isset( $flags['-'] ) ) {
99  $flags = array( '-' => true );// remove other flags
100  } elseif ( count( $flags ) == 1 && isset( $flags['T'] ) ) {
101  $flags['H'] = true;
102  } elseif ( isset( $flags['H'] ) ) {
103  // replace A flag, and remove other flags except T
104  $temp = array( '+' => true, 'H' => true );
105  if ( isset( $flags['T'] ) ) {
106  $temp['T'] = true;
107  }
108  if ( isset( $flags['D'] ) ) {
109  $temp['D'] = true;
110  }
111  $flags = $temp;
112  } else {
113  if ( isset( $flags['A'] ) ) {
114  $flags['+'] = true;
115  $flags['S'] = true;
116  }
117  if ( isset( $flags['D'] ) ) {
118  unset( $flags['S'] );
119  }
120  // try to find flags like "zh-hans", "zh-hant"
121  // allow syntaxes like "-{zh-hans;zh-hant|XXXX}-"
122  $variantFlags = array_intersect( array_keys( $flags ), $this->mConverter->mVariants );
123  if ( $variantFlags ) {
124  $variantFlags = array_flip( $variantFlags );
125  $flags = array();
126  }
127  }
128  $this->mVariantFlags = $variantFlags;
129  $this->mRules = $text;
130  $this->mFlags = $flags;
131  }
132 
137  function parseRules() {
138  $rules = $this->mRules;
139  $bidtable = array();
140  $unidtable = array();
141  $variants = $this->mConverter->mVariants;
142  $varsep_pattern = $this->mConverter->getVarSeparatorPattern();
143 
144  // Split according to $varsep_pattern, but ignore semicolons from HTML entities
145  $rules = preg_replace( '/(&[#a-zA-Z0-9]+);/', "$1\x01", $rules );
146  $choice = preg_split( $varsep_pattern, $rules );
147  $choice = str_replace( "\x01", ';', $choice );
148 
149  foreach ( $choice as $c ) {
150  $v = explode( ':', $c, 2 );
151  if ( count( $v ) != 2 ) {
152  // syntax error, skip
153  continue;
154  }
155  $to = trim( $v[1] );
156  $v = trim( $v[0] );
157  $u = explode( '=>', $v, 2 );
158  // if $to is empty, strtr() could return a wrong result
159  if ( count( $u ) == 1 && $to && in_array( $v, $variants ) ) {
160  $bidtable[$v] = $to;
161  } elseif ( count( $u ) == 2 ) {
162  $from = trim( $u[0] );
163  $v = trim( $u[1] );
164  if ( array_key_exists( $v, $unidtable )
165  && !is_array( $unidtable[$v] )
166  && $to
167  && in_array( $v, $variants ) ) {
168  $unidtable[$v] = array( $from => $to );
169  } elseif ( $to && in_array( $v, $variants ) ) {
170  $unidtable[$v][$from] = $to;
171  }
172  }
173  // syntax error, pass
174  if ( !isset( $this->mConverter->mVariantNames[$v] ) ) {
175  $bidtable = array();
176  $unidtable = array();
177  break;
178  }
179  }
180  $this->mBidtable = $bidtable;
181  $this->mUnidtable = $unidtable;
182  }
183 
189  function getRulesDesc() {
190  $codesep = $this->mConverter->mDescCodeSep;
191  $varsep = $this->mConverter->mDescVarSep;
192  $text = '';
193  foreach ( $this->mBidtable as $k => $v ) {
194  $text .= $this->mConverter->mVariantNames[$k] . "$codesep$v$varsep";
195  }
196  foreach ( $this->mUnidtable as $k => $a ) {
197  foreach ( $a as $from => $to ) {
198  $text .= $from . '⇒' . $this->mConverter->mVariantNames[$k] .
199  "$codesep$to$varsep";
200  }
201  }
202  return $text;
203  }
204 
213  function getRuleConvertedStr( $variant ) {
214  $bidtable = $this->mBidtable;
215  $unidtable = $this->mUnidtable;
216 
217  if ( count( $bidtable ) + count( $unidtable ) == 0 ) {
218  return $this->mRules;
219  } else {
220  // display current variant in bidirectional array
221  $disp = $this->getTextInBidtable( $variant );
222  // or display current variant in fallbacks
223  if ( !$disp ) {
224  $disp = $this->getTextInBidtable(
225  $this->mConverter->getVariantFallbacks( $variant ) );
226  }
227  // or display current variant in unidirectional array
228  if ( !$disp && array_key_exists( $variant, $unidtable ) ) {
229  $disp = array_values( $unidtable[$variant] );
230  $disp = $disp[0];
231  }
232  // or display frist text under disable manual convert
233  if ( !$disp && $this->mConverter->mManualLevel[$variant] == 'disable' ) {
234  if ( count( $bidtable ) > 0 ) {
235  $disp = array_values( $bidtable );
236  $disp = $disp[0];
237  } else {
238  $disp = array_values( $unidtable );
239  $disp = array_values( $disp[0] );
240  $disp = $disp[0];
241  }
242  }
243  return $disp;
244  }
245  }
246 
257  function getRuleConvertedTitle( $variant ) {
258  if ( $variant === $this->mConverter->mMainLanguageCode ) {
259  // If a string targeting exactly this variant is set,
260  // use it. Otherwise, just return false, so the real
261  // page name can be shown (and because variant === main,
262  // there'll be no further automatic conversion).
263  $disp = $this->getTextInBidtable( $variant );
264  if ( $disp ) {
265  return $disp;
266  }
267  if ( array_key_exists( $variant, $this->mUnidtable ) ) {
268  $disp = array_values( $this->mUnidtable[$variant] );
269  $disp = $disp[0];
270  }
271  // Assigned above or still false.
272  return $disp;
273  } else {
274  return $this->getRuleConvertedStr( $variant );
275  }
276  }
277 
282  function generateConvTable() {
283  // Special case optimisation
284  if ( !$this->mBidtable && !$this->mUnidtable ) {
285  $this->mConvTable = array();
286  return;
287  }
288 
289  $bidtable = $this->mBidtable;
290  $unidtable = $this->mUnidtable;
291  $manLevel = $this->mConverter->mManualLevel;
292 
293  $vmarked = array();
294  foreach ( $this->mConverter->mVariants as $v ) {
295  /* for bidirectional array
296  fill in the missing variants, if any,
297  with fallbacks */
298  if ( !isset( $bidtable[$v] ) ) {
299  $variantFallbacks =
300  $this->mConverter->getVariantFallbacks( $v );
301  $vf = $this->getTextInBidtable( $variantFallbacks );
302  if ( $vf ) {
303  $bidtable[$v] = $vf;
304  }
305  }
306 
307  if ( isset( $bidtable[$v] ) ) {
308  foreach ( $vmarked as $vo ) {
309  // use syntax: -{A|zh:WordZh;zh-tw:WordTw}-
310  // or -{H|zh:WordZh;zh-tw:WordTw}-
311  // or -{-|zh:WordZh;zh-tw:WordTw}-
312  // to introduce a custom mapping between
313  // words WordZh and WordTw in the whole text
314  if ( $manLevel[$v] == 'bidirectional' ) {
315  $this->mConvTable[$v][$bidtable[$vo]] = $bidtable[$v];
316  }
317  if ( $manLevel[$vo] == 'bidirectional' ) {
318  $this->mConvTable[$vo][$bidtable[$v]] = $bidtable[$vo];
319  }
320  }
321  $vmarked[] = $v;
322  }
323  /* for unidirectional array fill to convert tables */
324  if ( ( $manLevel[$v] == 'bidirectional' || $manLevel[$v] == 'unidirectional' )
325  && isset( $unidtable[$v] )
326  ) {
327  if ( isset( $this->mConvTable[$v] ) ) {
328  $this->mConvTable[$v] = array_merge( $this->mConvTable[$v], $unidtable[$v] );
329  } else {
330  $this->mConvTable[$v] = $unidtable[$v];
331  }
332  }
333  }
334  }
335 
340  public function parse( $variant = null ) {
341  if ( !$variant ) {
342  $variant = $this->mConverter->getPreferredVariant();
343  }
344 
345  $this->parseFlags();
347 
348  // convert to specified variant
349  // syntax: -{zh-hans;zh-hant[;...]|<text to convert>}-
350  if ( $this->mVariantFlags ) {
351  // check if current variant in flags
352  if ( isset( $this->mVariantFlags[$variant] ) ) {
353  // then convert <text to convert> to current language
354  $this->mRules = $this->mConverter->autoConvert( $this->mRules,
355  $variant );
356  } else {
357  // if current variant no in flags,
358  // then we check its fallback variants.
359  $variantFallbacks =
360  $this->mConverter->getVariantFallbacks( $variant );
361  if ( is_array( $variantFallbacks ) ) {
362  foreach ( $variantFallbacks as $variantFallback ) {
363  // if current variant's fallback exist in flags
364  if ( isset( $this->mVariantFlags[$variantFallback] ) ) {
365  // then convert <text to convert> to fallback language
366  $this->mRules =
367  $this->mConverter->autoConvert( $this->mRules,
368  $variantFallback );
369  break;
370  }
371  }
372  }
373  }
374  $this->mFlags = $flags = array( 'R' => true );
375  }
376 
377  if ( !isset( $flags['R'] ) && !isset( $flags['N'] ) ) {
378  // decode => HTML entities modified by Sanitizer::removeHTMLtags
379  $this->mRules = str_replace( '=&gt;', '=>', $this->mRules );
380  $this->parseRules();
381  }
382  $rules = $this->mRules;
383 
384  if ( !$this->mBidtable && !$this->mUnidtable ) {
385  if ( isset( $flags['+'] ) || isset( $flags['-'] ) ) {
386  // fill all variants if text in -{A/H/-|text} without rules
387  foreach ( $this->mConverter->mVariants as $v ) {
388  $this->mBidtable[$v] = $rules;
389  }
390  } elseif ( !isset( $flags['N'] ) && !isset( $flags['T'] ) ) {
391  $this->mFlags = $flags = array( 'R' => true );
392  }
393  }
394 
395  $this->mRuleDisplay = false;
396  foreach ( $flags as $flag => $unused ) {
397  switch ( $flag ) {
398  case 'R':
399  // if we don't do content convert, still strip the -{}- tags
400  $this->mRuleDisplay = $rules;
401  break;
402  case 'N':
403  // process N flag: output current variant name
404  $ruleVar = trim( $rules );
405  if ( isset( $this->mConverter->mVariantNames[$ruleVar] ) ) {
406  $this->mRuleDisplay = $this->mConverter->mVariantNames[$ruleVar];
407  } else {
408  $this->mRuleDisplay = '';
409  }
410  break;
411  case 'D':
412  // process D flag: output rules description
413  $this->mRuleDisplay = $this->getRulesDesc();
414  break;
415  case 'H':
416  // process H,- flag or T only: output nothing
417  $this->mRuleDisplay = '';
418  break;
419  case '-':
420  $this->mRulesAction = 'remove';
421  $this->mRuleDisplay = '';
422  break;
423  case '+':
424  $this->mRulesAction = 'add';
425  $this->mRuleDisplay = '';
426  break;
427  case 'S':
428  $this->mRuleDisplay = $this->getRuleConvertedStr( $variant );
429  break;
430  case 'T':
431  $this->mRuleTitle = $this->getRuleConvertedTitle( $variant );
432  $this->mRuleDisplay = '';
433  break;
434  default:
435  // ignore unknown flags (but see error case below)
436  }
437  }
438  if ( $this->mRuleDisplay === false ) {
439  $this->mRuleDisplay = '<span class="error">'
440  . wfMessage( 'converter-manual-rule-error' )->inContentLanguage()->escaped()
441  . '</span>';
442  }
443 
444  $this->generateConvTable();
445  }
446 
450  public function hasRules() {
451  // TODO:
452  }
453 
458  public function getDisplay() {
459  return $this->mRuleDisplay;
460  }
461 
466  public function getTitle() {
467  return $this->mRuleTitle;
468  }
469 
474  public function getRulesAction() {
475  return $this->mRulesAction;
476  }
477 
483  public function getConvTable() {
484  return $this->mConvTable;
485  }
486 
491  public function getRules() {
492  return $this->mRules;
493  }
494 
499  public function getFlags() {
500  return $this->mFlags;
501  }
502 }
ConverterRule\$mConverter
$mConverter
Definition: ConverterRule.php:29
ConverterRule
Parser for rules of language conversion , parse rules in -{ }- tag.
Definition: ConverterRule.php:27
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
ConverterRule\$mBidtable
$mBidtable
Definition: ConverterRule.php:37
ConverterRule\getDisplay
getDisplay()
Get display text on markup -{...}-.
Definition: ConverterRule.php:458
ConverterRule\$mConvTable
$mConvTable
Definition: ConverterRule.php:36
ConverterRule\$mRuleDisplay
$mRuleDisplay
Definition: ConverterRule.php:30
$f
$f
Definition: UtfNormalTest2.php:38
$from
$from
Definition: importImages.php:90
ConverterRule\$mRulesAction
$mRulesAction
Definition: ConverterRule.php:33
ConverterRule\getRulesDesc
getRulesDesc()
Definition: ConverterRule.php:189
ConverterRule\getFlags
getFlags()
Get conversion flags.
Definition: ConverterRule.php:499
$flags
it s the revision text itself In either if gzip is the revision text is gzipped $flags
Definition: hooks.txt:2113
ConverterRule\$mFlags
$mFlags
Definition: ConverterRule.php:34
ConverterRule\getRuleConvertedTitle
getRuleConvertedTitle( $variant)
Similar to getRuleConvertedStr(), but this prefers to use original page title if $variant === $this->...
Definition: ConverterRule.php:257
ConverterRule\$mText
$mText
Definition: ConverterRule.php:28
StringUtils\explode
static explode( $separator, $subject)
Workalike for explode() with limited memory usage.
Definition: StringUtils.php:310
wfMessage
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses after processing after in associative array form externallinks including delete and has completed for all link tables default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock() - offset Set to overwrite offset parameter in $wgRequest set to '' to unset offset - wrap String Wrap the message in html(usually something like "&lt
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
ConverterRule\parse
parse( $variant=null)
Parse rules and flags.
Definition: ConverterRule.php:340
ConverterRule\getTextInBidtable
getTextInBidtable( $variants)
Check if variants array in convert array.
Definition: ConverterRule.php:57
ConverterRule\getConvTable
getConvTable()
Get conversion table.
Definition: ConverterRule.php:483
ConverterRule\getRules
getRules()
Get conversion rules string.
Definition: ConverterRule.php:491
ConverterRule\parseRules
parseRules()
Generate conversion table.
Definition: ConverterRule.php:137
ConverterRule\getRulesAction
getRulesAction()
Return how deal with conversion rules.
Definition: ConverterRule.php:474
ConverterRule\__construct
__construct( $text, $converter)
Constructor.
Definition: ConverterRule.php:46
ConverterRule\$mRules
$mRules
Definition: ConverterRule.php:32
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
ConverterRule\$mUnidtable
$mUnidtable
Definition: ConverterRule.php:38
ConverterRule\parseFlags
parseFlags()
Parse flags with syntax -{FLAG| ...
Definition: ConverterRule.php:74
ConverterRule\hasRules
hasRules()
Definition: ConverterRule.php:450
ConverterRule\getRuleConvertedStr
getRuleConvertedStr( $variant)
Parse rules conversion.
Definition: ConverterRule.php:213
ConverterRule\generateConvTable
generateConvTable()
Generate conversion table for all text.
Definition: ConverterRule.php:282
ConverterRule\$mVariantFlags
$mVariantFlags
Definition: ConverterRule.php:35
ConverterRule\getTitle
getTitle()
Get converted title.
Definition: ConverterRule.php:466
ConverterRule\$mRuleTitle
$mRuleTitle
Definition: ConverterRule.php:31