Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like CoreParserFunctions often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use CoreParserFunctions, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 28 | class CoreParserFunctions { |
||
| 29 | /** |
||
| 30 | * @param Parser $parser |
||
| 31 | * @return void |
||
| 32 | */ |
||
| 33 | public static function register( $parser ) { |
||
| 89 | |||
| 90 | /** |
||
| 91 | * @param Parser $parser |
||
| 92 | * @param string $part1 |
||
| 93 | * @return array |
||
| 94 | */ |
||
| 95 | public static function intFunction( $parser, $part1 = '' /*, ... */ ) { |
||
| 110 | |||
| 111 | /** |
||
| 112 | * @param Parser $parser |
||
| 113 | * @param string $date |
||
| 114 | * @param string $defaultPref |
||
| 115 | * |
||
| 116 | * @return string |
||
| 117 | */ |
||
| 118 | public static function formatDate( $parser, $date, $defaultPref = null ) { |
||
| 135 | |||
| 136 | public static function ns( $parser, $part1 = '' ) { |
||
| 149 | |||
| 150 | public static function nse( $parser, $part1 = '' ) { |
||
| 157 | |||
| 158 | /** |
||
| 159 | * urlencodes a string according to one of three patterns: (bug 22474) |
||
| 160 | * |
||
| 161 | * By default (for HTTP "query" strings), spaces are encoded as '+'. |
||
| 162 | * Or to encode a value for the HTTP "path", spaces are encoded as '%20'. |
||
| 163 | * For links to "wiki"s, or similar software, spaces are encoded as '_', |
||
| 164 | * |
||
| 165 | * @param Parser $parser |
||
| 166 | * @param string $s The text to encode. |
||
| 167 | * @param string $arg (optional): The type of encoding. |
||
| 168 | * @return string |
||
| 169 | */ |
||
| 170 | public static function urlencode( $parser, $s = '', $arg = null ) { |
||
| 197 | |||
| 198 | public static function lcfirst( $parser, $s = '' ) { |
||
| 202 | |||
| 203 | public static function ucfirst( $parser, $s = '' ) { |
||
| 207 | |||
| 208 | /** |
||
| 209 | * @param Parser $parser |
||
| 210 | * @param string $s |
||
| 211 | * @return string |
||
| 212 | */ |
||
| 213 | public static function lc( $parser, $s = '' ) { |
||
| 217 | |||
| 218 | /** |
||
| 219 | * @param Parser $parser |
||
| 220 | * @param string $s |
||
| 221 | * @return string |
||
| 222 | */ |
||
| 223 | public static function uc( $parser, $s = '' ) { |
||
| 227 | |||
| 228 | public static function localurl( $parser, $s = '', $arg = null ) { |
||
| 231 | |||
| 232 | View Code Duplication | public static function localurle( $parser, $s = '', $arg = null ) { |
|
| 240 | |||
| 241 | public static function fullurl( $parser, $s = '', $arg = null ) { |
||
| 244 | |||
| 245 | View Code Duplication | public static function fullurle( $parser, $s = '', $arg = null ) { |
|
| 253 | |||
| 254 | public static function canonicalurl( $parser, $s = '', $arg = null ) { |
||
| 257 | |||
| 258 | View Code Duplication | public static function canonicalurle( $parser, $s = '', $arg = null ) { |
|
| 266 | |||
| 267 | public static function urlFunction( $func, $s = '', $arg = null ) { |
||
| 291 | |||
| 292 | /** |
||
| 293 | * @param Parser $parser |
||
| 294 | * @param string $num |
||
| 295 | * @param string $arg |
||
| 296 | * @return string |
||
| 297 | */ |
||
| 298 | public static function formatnum( $parser, $num = '', $arg = null ) { |
||
| 308 | |||
| 309 | /** |
||
| 310 | * @param Parser $parser |
||
| 311 | * @param string $case |
||
| 312 | * @param string $word |
||
| 313 | * @return string |
||
| 314 | */ |
||
| 315 | public static function grammar( $parser, $case = '', $word = '' ) { |
||
| 319 | |||
| 320 | /** |
||
| 321 | * @param Parser $parser |
||
| 322 | * @param string $username |
||
| 323 | * @return string |
||
| 324 | */ |
||
| 325 | public static function gender( $parser, $username ) { |
||
| 357 | |||
| 358 | /** |
||
| 359 | * @param Parser $parser |
||
| 360 | * @param string $text |
||
| 361 | * @return string |
||
| 362 | */ |
||
| 363 | public static function plural( $parser, $text = '' ) { |
||
| 369 | |||
| 370 | /** |
||
| 371 | * @param Parser $parser |
||
| 372 | * @param string $text |
||
| 373 | * @return string |
||
| 374 | */ |
||
| 375 | public static function bidi( $parser, $text = '' ) { |
||
| 378 | |||
| 379 | /** |
||
| 380 | * Override the title of the page when viewed, provided we've been given a |
||
| 381 | * title which will normalise to the canonical title |
||
| 382 | * |
||
| 383 | * @param Parser $parser Parent parser |
||
| 384 | * @param string $text Desired title text |
||
| 385 | * @param string $uarg |
||
| 386 | * @return string |
||
| 387 | */ |
||
| 388 | public static function displaytitle( $parser, $text = '', $uarg = '' ) { |
||
| 389 | global $wgRestrictDisplayTitle; |
||
| 390 | |||
| 391 | static $magicWords = null; |
||
| 392 | if ( is_null( $magicWords ) ) { |
||
| 393 | $magicWords = new MagicWordArray( [ 'displaytitle_noerror', 'displaytitle_noreplace' ] ); |
||
| 394 | } |
||
| 395 | $arg = $magicWords->matchStartToEnd( $uarg ); |
||
| 396 | |||
| 397 | // parse a limited subset of wiki markup (just the single quote items) |
||
| 398 | $text = $parser->doQuotes( $text ); |
||
| 399 | |||
| 400 | // remove stripped text (e.g. the UNIQ-QINU stuff) that was generated by tag extensions/whatever |
||
| 401 | $text = $parser->killMarkers( $text ); |
||
| 402 | |||
| 403 | // list of disallowed tags for DISPLAYTITLE |
||
| 404 | // these will be escaped even though they are allowed in normal wiki text |
||
| 405 | $bad = [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'blockquote', 'ol', 'ul', 'li', 'hr', |
||
| 406 | 'table', 'tr', 'th', 'td', 'dl', 'dd', 'caption', 'p', 'ruby', 'rb', 'rt', 'rtc', 'rp', 'br' ]; |
||
| 407 | |||
| 408 | // disallow some styles that could be used to bypass $wgRestrictDisplayTitle |
||
| 409 | if ( $wgRestrictDisplayTitle ) { |
||
| 410 | $htmlTagsCallback = function ( &$params ) { |
||
| 411 | $decoded = Sanitizer::decodeTagAttributes( $params ); |
||
| 412 | |||
| 413 | if ( isset( $decoded['style'] ) ) { |
||
| 414 | // this is called later anyway, but we need it right now for the regexes below to be safe |
||
| 415 | // calling it twice doesn't hurt |
||
| 416 | $decoded['style'] = Sanitizer::checkCss( $decoded['style'] ); |
||
| 417 | |||
| 418 | if ( preg_match( '/(display|user-select|visibility)\s*:/i', $decoded['style'] ) ) { |
||
| 419 | $decoded['style'] = '/* attempt to bypass $wgRestrictDisplayTitle */'; |
||
| 420 | } |
||
| 421 | } |
||
| 422 | |||
| 423 | $params = Sanitizer::safeEncodeTagAttributes( $decoded ); |
||
| 424 | }; |
||
| 425 | } else { |
||
| 426 | $htmlTagsCallback = null; |
||
| 427 | } |
||
| 428 | |||
| 429 | // only requested titles that normalize to the actual title are allowed through |
||
| 430 | // if $wgRestrictDisplayTitle is true (it is by default) |
||
| 431 | // mimic the escaping process that occurs in OutputPage::setPageTitle |
||
| 432 | $text = Sanitizer::normalizeCharReferences( Sanitizer::removeHTMLtags( |
||
| 433 | $text, |
||
| 434 | $htmlTagsCallback, |
||
| 435 | [], |
||
| 436 | [], |
||
| 437 | $bad |
||
| 438 | ) ); |
||
| 439 | $title = Title::newFromText( Sanitizer::stripAllTags( $text ) ); |
||
| 440 | |||
| 441 | if ( !$wgRestrictDisplayTitle || |
||
| 442 | ( $title instanceof Title |
||
| 443 | && !$title->hasFragment() |
||
| 444 | && $title->equals( $parser->mTitle ) ) |
||
| 445 | ) { |
||
| 446 | $old = $parser->mOutput->getProperty( 'displaytitle' ); |
||
| 447 | if ( $old === false || $arg !== 'displaytitle_noreplace' ) { |
||
| 448 | $parser->mOutput->setDisplayTitle( $text ); |
||
| 449 | } |
||
| 450 | if ( $old !== false && $old !== $text && !$arg ) { |
||
| 451 | $converter = $parser->getConverterLanguage()->getConverter(); |
||
| 452 | return '<span class="error">' . |
||
| 453 | wfMessage( 'duplicate-displaytitle', |
||
| 454 | // Message should be parsed, but these params should only be escaped. |
||
| 455 | $converter->markNoConversion( wfEscapeWikiText( $old ) ), |
||
| 456 | $converter->markNoConversion( wfEscapeWikiText( $text ) ) |
||
| 457 | )->inContentLanguage()->text() . |
||
| 458 | '</span>'; |
||
| 459 | } else { |
||
| 460 | return ''; |
||
| 461 | } |
||
| 462 | } else { |
||
| 463 | $converter = $parser->getConverterLanguage()->getConverter(); |
||
| 464 | $parser->getOutput()->addWarning( |
||
| 465 | wfMessage( 'restricted-displaytitle', |
||
| 466 | // Message should be parsed, but this param should only be escaped. |
||
| 467 | $converter->markNoConversion( wfEscapeWikiText( $text ) ) |
||
| 468 | )->text() |
||
| 469 | ); |
||
| 470 | $parser->addTrackingCategory( 'restricted-displaytitle-ignored' ); |
||
| 471 | } |
||
| 472 | } |
||
| 473 | |||
| 474 | /** |
||
| 475 | * Matches the given value against the value of given magic word |
||
| 476 | * |
||
| 477 | * @param string $magicword Magic word key |
||
| 478 | * @param string $value Value to match |
||
| 479 | * @return bool True on successful match |
||
| 480 | */ |
||
| 481 | private static function matchAgainstMagicword( $magicword, $value ) { |
||
| 489 | |||
| 490 | public static function formatRaw( $num, $raw ) { |
||
| 525 | |||
| 526 | /** |
||
| 527 | * Given a title, return the namespace name that would be given by the |
||
| 528 | * corresponding magic word |
||
| 529 | * Note: function name changed to "mwnamespace" rather than "namespace" |
||
| 530 | * to not break PHP 5.3 |
||
| 531 | * @param Parser $parser |
||
| 532 | * @param string $title |
||
| 533 | * @return mixed|string |
||
| 534 | */ |
||
| 535 | public static function mwnamespace( $parser, $title = null ) { |
||
| 584 | |||
| 585 | /** |
||
| 586 | * Functions to get and normalize pagenames, corresponding to the magic words |
||
| 587 | * of the same names |
||
| 588 | * @param Parser $parser |
||
| 589 | * @param string $title |
||
| 590 | * @return string |
||
| 591 | */ |
||
| 592 | View Code Duplication | public static function pagename( $parser, $title = null ) { |
|
| 690 | |||
| 691 | /** |
||
| 692 | * Return the number of pages, files or subcats in the given category, |
||
| 693 | * or 0 if it's nonexistent. This is an expensive parser function and |
||
| 694 | * can't be called too many times per page. |
||
| 695 | * @param Parser $parser |
||
| 696 | * @param string $name |
||
| 697 | * @param string $arg1 |
||
| 698 | * @param string $arg2 |
||
| 699 | * @return string |
||
| 700 | */ |
||
| 701 | public static function pagesincategory( $parser, $name = '', $arg1 = null, $arg2 = null ) { |
||
| 758 | |||
| 759 | /** |
||
| 760 | * Return the size of the given page, or 0 if it's nonexistent. This is an |
||
| 761 | * expensive parser function and can't be called too many times per page. |
||
| 762 | * |
||
| 763 | * @param Parser $parser |
||
| 764 | * @param string $page Name of page to check (Default: empty string) |
||
| 765 | * @param string $raw Should number be human readable with commas or just number |
||
| 766 | * @return string |
||
| 767 | */ |
||
| 768 | public static function pagesize( $parser, $page = '', $raw = null ) { |
||
| 769 | $title = Title::newFromText( $page ); |
||
| 770 | |||
| 771 | if ( !is_object( $title ) ) { |
||
| 772 | return self::formatRaw( 0, $raw ); |
||
| 773 | } |
||
| 774 | |||
| 775 | // fetch revision from cache/database and return the value |
||
| 776 | $rev = self::getCachedRevisionObject( $parser, $title ); |
||
| 777 | $length = $rev ? $rev->getSize() : 0; |
||
| 778 | if ( $length === null ) { |
||
| 779 | // We've had bugs where rev_len was not being recorded for empty pages, see T135414 |
||
| 780 | $length = 0; |
||
| 781 | } |
||
| 782 | return self::formatRaw( $length, $raw ); |
||
| 783 | } |
||
| 784 | |||
| 785 | /** |
||
| 786 | * Returns the requested protection level for the current page. This |
||
| 787 | * is an expensive parser function and can't be called too many times |
||
| 788 | * per page, unless the protection levels/expiries for the given title |
||
| 789 | * have already been retrieved |
||
| 790 | * |
||
| 791 | * @param Parser $parser |
||
| 792 | * @param string $type |
||
| 793 | * @param string $title |
||
| 794 | * |
||
| 795 | * @return string |
||
| 796 | */ |
||
| 797 | View Code Duplication | public static function protectionlevel( $parser, $type = '', $title = '' ) { |
|
| 810 | |||
| 811 | /** |
||
| 812 | * Returns the requested protection expiry for the current page. This |
||
| 813 | * is an expensive parser function and can't be called too many times |
||
| 814 | * per page, unless the protection levels/expiries for the given title |
||
| 815 | * have already been retrieved |
||
| 816 | * |
||
| 817 | * @param Parser $parser |
||
| 818 | * @param string $type |
||
| 819 | * @param string $title |
||
| 820 | * |
||
| 821 | * @return string |
||
| 822 | */ |
||
| 823 | View Code Duplication | public static function protectionexpiry( $parser, $type = '', $title = '' ) { |
|
| 839 | |||
| 840 | /** |
||
| 841 | * Gives language names. |
||
| 842 | * @param Parser $parser |
||
| 843 | * @param string $code Language code (of which to get name) |
||
| 844 | * @param string $inLanguage Language code (in which to get name) |
||
| 845 | * @return string |
||
| 846 | */ |
||
| 847 | public static function language( $parser, $code = '', $inLanguage = '' ) { |
||
| 853 | |||
| 854 | /** |
||
| 855 | * Unicode-safe str_pad with the restriction that $length is forced to be <= 500 |
||
| 856 | * @param Parser $parser |
||
| 857 | * @param string $string |
||
| 858 | * @param int $length |
||
| 859 | * @param string $padding |
||
| 860 | * @param int $direction |
||
| 861 | * @return string |
||
| 862 | */ |
||
| 863 | public static function pad( |
||
| 890 | |||
| 891 | public static function padleft( $parser, $string = '', $length = 0, $padding = '0' ) { |
||
| 894 | |||
| 895 | public static function padright( $parser, $string = '', $length = 0, $padding = '0' ) { |
||
| 898 | |||
| 899 | /** |
||
| 900 | * @param Parser $parser |
||
| 901 | * @param string $text |
||
| 902 | * @return string |
||
| 903 | */ |
||
| 904 | public static function anchorencode( $parser, $text ) { |
||
| 908 | |||
| 909 | public static function special( $parser, $text ) { |
||
| 920 | |||
| 921 | public static function speciale( $parser, $text ) { |
||
| 924 | |||
| 925 | /** |
||
| 926 | * @param Parser $parser |
||
| 927 | * @param string $text The sortkey to use |
||
| 928 | * @param string $uarg Either "noreplace" or "noerror" (in en) |
||
| 929 | * both suppress errors, and noreplace does nothing if |
||
| 930 | * a default sortkey already exists. |
||
| 931 | * @return string |
||
| 932 | */ |
||
| 933 | public static function defaultsort( $parser, $text, $uarg = '' ) { |
||
| 934 | static $magicWords = null; |
||
| 935 | if ( is_null( $magicWords ) ) { |
||
| 936 | $magicWords = new MagicWordArray( [ 'defaultsort_noerror', 'defaultsort_noreplace' ] ); |
||
| 937 | } |
||
| 938 | $arg = $magicWords->matchStartToEnd( $uarg ); |
||
| 939 | |||
| 940 | $text = trim( $text ); |
||
| 941 | if ( strlen( $text ) == 0 ) { |
||
| 942 | return ''; |
||
| 943 | } |
||
| 944 | $old = $parser->getCustomDefaultSort(); |
||
| 945 | if ( $old === false || $arg !== 'defaultsort_noreplace' ) { |
||
| 946 | $parser->setDefaultSort( $text ); |
||
| 947 | } |
||
| 948 | |||
| 949 | if ( $old === false || $old == $text || $arg ) { |
||
| 950 | return ''; |
||
| 951 | } else { |
||
| 952 | $converter = $parser->getConverterLanguage()->getConverter(); |
||
| 953 | return '<span class="error">' . |
||
| 954 | wfMessage( 'duplicate-defaultsort', |
||
| 955 | // Message should be parsed, but these params should only be escaped. |
||
| 956 | $converter->markNoConversion( wfEscapeWikiText( $old ) ), |
||
| 957 | $converter->markNoConversion( wfEscapeWikiText( $text ) ) |
||
| 958 | )->inContentLanguage()->text() . |
||
| 959 | '</span>'; |
||
| 960 | } |
||
| 961 | } |
||
| 962 | |||
| 963 | /** |
||
| 964 | * Usage {{filepath|300}}, {{filepath|nowiki}}, {{filepath|nowiki|300}} |
||
| 965 | * or {{filepath|300|nowiki}} or {{filepath|300px}}, {{filepath|200x300px}}, |
||
| 966 | * {{filepath|nowiki|200x300px}}, {{filepath|200x300px|nowiki}}. |
||
| 967 | * |
||
| 968 | * @param Parser $parser |
||
| 969 | * @param string $name |
||
| 970 | * @param string $argA |
||
| 971 | * @param string $argB |
||
| 972 | * @return array|string |
||
| 973 | */ |
||
| 974 | public static function filepath( $parser, $name = '', $argA = '', $argB = '' ) { |
||
| 1007 | |||
| 1008 | /** |
||
| 1009 | * Parser function to extension tag adaptor |
||
| 1010 | * @param Parser $parser |
||
| 1011 | * @param PPFrame $frame |
||
| 1012 | * @param PPNode[] $args |
||
| 1013 | * @return string |
||
| 1014 | */ |
||
| 1015 | public static function tagObj( $parser, $frame, $args ) { |
||
| 1061 | |||
| 1062 | /** |
||
| 1063 | * Fetched the current revision of the given title and return this. |
||
| 1064 | * Will increment the expensive function count and |
||
| 1065 | * add a template link to get the value refreshed on changes. |
||
| 1066 | * For a given title, which is equal to the current parser title, |
||
| 1067 | * the revision object from the parser is used, when that is the current one |
||
| 1068 | * |
||
| 1069 | * @param Parser $parser |
||
| 1070 | * @param Title $title |
||
| 1071 | * @return Revision |
||
| 1072 | * @since 1.23 |
||
| 1073 | */ |
||
| 1074 | private static function getCachedRevisionObject( $parser, $title = null ) { |
||
| 1107 | |||
| 1108 | /** |
||
| 1109 | * Get the pageid of a specified page |
||
| 1110 | * @param Parser $parser |
||
| 1111 | * @param string $title Title to get the pageid from |
||
| 1112 | * @return int|null|string |
||
| 1113 | * @since 1.23 |
||
| 1114 | */ |
||
| 1115 | public static function pageid( $parser, $title = null ) { |
||
| 1152 | |||
| 1153 | /** |
||
| 1154 | * Get the id from the last revision of a specified page. |
||
| 1155 | * @param Parser $parser |
||
| 1156 | * @param string $title Title to get the id from |
||
| 1157 | * @return int|null|string |
||
| 1158 | * @since 1.23 |
||
| 1159 | */ |
||
| 1160 | View Code Duplication | public static function revisionid( $parser, $title = null ) { |
|
| 1169 | |||
| 1170 | /** |
||
| 1171 | * Get the day from the last revision of a specified page. |
||
| 1172 | * @param Parser $parser |
||
| 1173 | * @param string $title Title to get the day from |
||
| 1174 | * @return string |
||
| 1175 | * @since 1.23 |
||
| 1176 | */ |
||
| 1177 | View Code Duplication | public static function revisionday( $parser, $title = null ) { |
|
| 1186 | |||
| 1187 | /** |
||
| 1188 | * Get the day with leading zeros from the last revision of a specified page. |
||
| 1189 | * @param Parser $parser |
||
| 1190 | * @param string $title Title to get the day from |
||
| 1191 | * @return string |
||
| 1192 | * @since 1.23 |
||
| 1193 | */ |
||
| 1194 | View Code Duplication | public static function revisionday2( $parser, $title = null ) { |
|
| 1203 | |||
| 1204 | /** |
||
| 1205 | * Get the month with leading zeros from the last revision of a specified page. |
||
| 1206 | * @param Parser $parser |
||
| 1207 | * @param string $title Title to get the month from |
||
| 1208 | * @return string |
||
| 1209 | * @since 1.23 |
||
| 1210 | */ |
||
| 1211 | View Code Duplication | public static function revisionmonth( $parser, $title = null ) { |
|
| 1220 | |||
| 1221 | /** |
||
| 1222 | * Get the month from the last revision of a specified page. |
||
| 1223 | * @param Parser $parser |
||
| 1224 | * @param string $title Title to get the month from |
||
| 1225 | * @return string |
||
| 1226 | * @since 1.23 |
||
| 1227 | */ |
||
| 1228 | View Code Duplication | public static function revisionmonth1( $parser, $title = null ) { |
|
| 1237 | |||
| 1238 | /** |
||
| 1239 | * Get the year from the last revision of a specified page. |
||
| 1240 | * @param Parser $parser |
||
| 1241 | * @param string $title Title to get the year from |
||
| 1242 | * @return string |
||
| 1243 | * @since 1.23 |
||
| 1244 | */ |
||
| 1245 | View Code Duplication | public static function revisionyear( $parser, $title = null ) { |
|
| 1254 | |||
| 1255 | /** |
||
| 1256 | * Get the timestamp from the last revision of a specified page. |
||
| 1257 | * @param Parser $parser |
||
| 1258 | * @param string $title Title to get the timestamp from |
||
| 1259 | * @return string |
||
| 1260 | * @since 1.23 |
||
| 1261 | */ |
||
| 1262 | View Code Duplication | public static function revisiontimestamp( $parser, $title = null ) { |
|
| 1271 | |||
| 1272 | /** |
||
| 1273 | * Get the user from the last revision of a specified page. |
||
| 1274 | * @param Parser $parser |
||
| 1275 | * @param string $title Title to get the user from |
||
| 1276 | * @return string |
||
| 1277 | * @since 1.23 |
||
| 1278 | */ |
||
| 1279 | View Code Duplication | public static function revisionuser( $parser, $title = null ) { |
|
| 1288 | |||
| 1289 | /** |
||
| 1290 | * Returns the sources of any cascading protection acting on a specified page. |
||
| 1291 | * Pages will not return their own title unless they transclude themselves. |
||
| 1292 | * This is an expensive parser function and can't be called too many times per page, |
||
| 1293 | * unless cascading protection sources for the page have already been loaded. |
||
| 1294 | * |
||
| 1295 | * @param Parser $parser |
||
| 1296 | * @param string $title |
||
| 1297 | * |
||
| 1298 | * @return string |
||
| 1299 | * @since 1.23 |
||
| 1300 | */ |
||
| 1301 | public static function cascadingsources( $parser, $title = '' ) { |
||
| 1318 | |||
| 1319 | } |
||
| 1320 |
In PHP, under loose comparison (like
==, or!=, orswitchconditions), values of different types might be equal.For
stringvalues, the empty string''is a special case, in particular the following results might be unexpected: