28 if ( !defined(
'MEDIAWIKI' ) ) {
29 echo
"This file is part of MediaWiki, it is not a valid entry point.\n";
33 use CLDRPluralRuleParser\Evaluator;
67 'sunday',
'monday',
'tuesday',
'wednesday',
'thursday',
72 'sun',
'mon',
'tue',
'wed',
'thu',
'fri',
'sat'
76 'january',
'february',
'march',
'april',
'may_long',
'june',
77 'july',
'august',
'september',
'october',
'november',
81 'january-gen',
'february-gen',
'march-gen',
'april-gen',
'may-gen',
'june-gen',
82 'july-gen',
'august-gen',
'september-gen',
'october-gen',
'november-gen',
86 'jan',
'feb',
'mar',
'apr',
'may',
'jun',
'jul',
'aug',
87 'sep',
'oct',
'nov',
'dec'
91 'iranian-calendar-m1',
'iranian-calendar-m2',
'iranian-calendar-m3',
92 'iranian-calendar-m4',
'iranian-calendar-m5',
'iranian-calendar-m6',
93 'iranian-calendar-m7',
'iranian-calendar-m8',
'iranian-calendar-m9',
94 'iranian-calendar-m10',
'iranian-calendar-m11',
'iranian-calendar-m12'
98 'hebrew-calendar-m1',
'hebrew-calendar-m2',
'hebrew-calendar-m3',
99 'hebrew-calendar-m4',
'hebrew-calendar-m5',
'hebrew-calendar-m6',
100 'hebrew-calendar-m7',
'hebrew-calendar-m8',
'hebrew-calendar-m9',
101 'hebrew-calendar-m10',
'hebrew-calendar-m11',
'hebrew-calendar-m12',
102 'hebrew-calendar-m6a',
'hebrew-calendar-m6b'
106 'hebrew-calendar-m1-gen',
'hebrew-calendar-m2-gen',
'hebrew-calendar-m3-gen',
107 'hebrew-calendar-m4-gen',
'hebrew-calendar-m5-gen',
'hebrew-calendar-m6-gen',
108 'hebrew-calendar-m7-gen',
'hebrew-calendar-m8-gen',
'hebrew-calendar-m9-gen',
109 'hebrew-calendar-m10-gen',
'hebrew-calendar-m11-gen',
'hebrew-calendar-m12-gen',
110 'hebrew-calendar-m6a-gen',
'hebrew-calendar-m6b-gen'
114 'hijri-calendar-m1',
'hijri-calendar-m2',
'hijri-calendar-m3',
115 'hijri-calendar-m4',
'hijri-calendar-m5',
'hijri-calendar-m6',
116 'hijri-calendar-m7',
'hijri-calendar-m8',
'hijri-calendar-m9',
117 'hijri-calendar-m10',
'hijri-calendar-m11',
'hijri-calendar-m12'
125 'millennia' => 31556952000,
126 'centuries' => 3155695200,
127 'decades' => 315569520,
153 static private $lre =
"\xE2\x80\xAA";
154 static private $rle =
"\xE2\x80\xAB";
155 static private $pdf =
"\xE2\x80\xAC";
170 static private $strongDirRegex =
'/(?:([\x{41}-\x{5a}\x{61}-\x{7a}\x{aa}\x{b5}\x{ba}\x{c0}-\x{d6}\x{d8}-\x{f6}\x{f8}-\x{2b8}\x{2bb}-\x{2c1}\x{2d0}\x{2d1}\x{2e0}-\x{2e4}\x{2ee}\x{370}-\x{373}\x{376}\x{377}\x{37a}-\x{37d}\x{37f}\x{386}\x{388}-\x{38a}\x{38c}\x{38e}-\x{3a1}\x{3a3}-\x{3f5}\x{3f7}-\x{482}\x{48a}-\x{52f}\x{531}-\x{556}\x{559}-\x{55f}\x{561}-\x{587}\x{589}\x{903}-\x{939}\x{93b}\x{93d}-\x{940}\x{949}-\x{94c}\x{94e}-\x{950}\x{958}-\x{961}\x{964}-\x{980}\x{982}\x{983}\x{985}-\x{98c}\x{98f}\x{990}\x{993}-\x{9a8}\x{9aa}-\x{9b0}\x{9b2}\x{9b6}-\x{9b9}\x{9bd}-\x{9c0}\x{9c7}\x{9c8}\x{9cb}\x{9cc}\x{9ce}\x{9d7}\x{9dc}\x{9dd}\x{9df}-\x{9e1}\x{9e6}-\x{9f1}\x{9f4}-\x{9fa}\x{a03}\x{a05}-\x{a0a}\x{a0f}\x{a10}\x{a13}-\x{a28}\x{a2a}-\x{a30}\x{a32}\x{a33}\x{a35}\x{a36}\x{a38}\x{a39}\x{a3e}-\x{a40}\x{a59}-\x{a5c}\x{a5e}\x{a66}-\x{a6f}\x{a72}-\x{a74}\x{a83}\x{a85}-\x{a8d}\x{a8f}-\x{a91}\x{a93}-\x{aa8}\x{aaa}-\x{ab0}\x{ab2}\x{ab3}\x{ab5}-\x{ab9}\x{abd}-\x{ac0}\x{ac9}\x{acb}\x{acc}\x{ad0}\x{ae0}\x{ae1}\x{ae6}-\x{af0}\x{af9}\x{b02}\x{b03}\x{b05}-\x{b0c}\x{b0f}\x{b10}\x{b13}-\x{b28}\x{b2a}-\x{b30}\x{b32}\x{b33}\x{b35}-\x{b39}\x{b3d}\x{b3e}\x{b40}\x{b47}\x{b48}\x{b4b}\x{b4c}\x{b57}\x{b5c}\x{b5d}\x{b5f}-\x{b61}\x{b66}-\x{b77}\x{b83}\x{b85}-\x{b8a}\x{b8e}-\x{b90}\x{b92}-\x{b95}\x{b99}\x{b9a}\x{b9c}\x{b9e}\x{b9f}\x{ba3}\x{ba4}\x{ba8}-\x{baa}\x{bae}-\x{bb9}\x{bbe}\x{bbf}\x{bc1}\x{bc2}\x{bc6}-\x{bc8}\x{bca}-\x{bcc}\x{bd0}\x{bd7}\x{be6}-\x{bf2}\x{c01}-\x{c03}\x{c05}-\x{c0c}\x{c0e}-\x{c10}\x{c12}-\x{c28}\x{c2a}-\x{c39}\x{c3d}\x{c41}-\x{c44}\x{c58}-\x{c5a}\x{c60}\x{c61}\x{c66}-\x{c6f}\x{c7f}\x{c82}\x{c83}\x{c85}-\x{c8c}\x{c8e}-\x{c90}\x{c92}-\x{ca8}\x{caa}-\x{cb3}\x{cb5}-\x{cb9}\x{cbd}-\x{cc4}\x{cc6}-\x{cc8}\x{cca}\x{ccb}\x{cd5}\x{cd6}\x{cde}\x{ce0}\x{ce1}\x{ce6}-\x{cef}\x{cf1}\x{cf2}\x{d02}\x{d03}\x{d05}-\x{d0c}\x{d0e}-\x{d10}\x{d12}-\x{d3a}\x{d3d}-\x{d40}\x{d46}-\x{d48}\x{d4a}-\x{d4c}\x{d4e}\x{d57}\x{d5f}-\x{d61}\x{d66}-\x{d75}\x{d79}-\x{d7f}\x{d82}\x{d83}\x{d85}-\x{d96}\x{d9a}-\x{db1}\x{db3}-\x{dbb}\x{dbd}\x{dc0}-\x{dc6}\x{dcf}-\x{dd1}\x{dd8}-\x{ddf}\x{de6}-\x{def}\x{df2}-\x{df4}\x{e01}-\x{e30}\x{e32}\x{e33}\x{e40}-\x{e46}\x{e4f}-\x{e5b}\x{e81}\x{e82}\x{e84}\x{e87}\x{e88}\x{e8a}\x{e8d}\x{e94}-\x{e97}\x{e99}-\x{e9f}\x{ea1}-\x{ea3}\x{ea5}\x{ea7}\x{eaa}\x{eab}\x{ead}-\x{eb0}\x{eb2}\x{eb3}\x{ebd}\x{ec0}-\x{ec4}\x{ec6}\x{ed0}-\x{ed9}\x{edc}-\x{edf}\x{f00}-\x{f17}\x{f1a}-\x{f34}\x{f36}\x{f38}\x{f3e}-\x{f47}\x{f49}-\x{f6c}\x{f7f}\x{f85}\x{f88}-\x{f8c}\x{fbe}-\x{fc5}\x{fc7}-\x{fcc}\x{fce}-\x{fda}\x{1000}-\x{102c}\x{1031}\x{1038}\x{103b}\x{103c}\x{103f}-\x{1057}\x{105a}-\x{105d}\x{1061}-\x{1070}\x{1075}-\x{1081}\x{1083}\x{1084}\x{1087}-\x{108c}\x{108e}-\x{109c}\x{109e}-\x{10c5}\x{10c7}\x{10cd}\x{10d0}-\x{1248}\x{124a}-\x{124d}\x{1250}-\x{1256}\x{1258}\x{125a}-\x{125d}\x{1260}-\x{1288}\x{128a}-\x{128d}\x{1290}-\x{12b0}\x{12b2}-\x{12b5}\x{12b8}-\x{12be}\x{12c0}\x{12c2}-\x{12c5}\x{12c8}-\x{12d6}\x{12d8}-\x{1310}\x{1312}-\x{1315}\x{1318}-\x{135a}\x{1360}-\x{137c}\x{1380}-\x{138f}\x{13a0}-\x{13f5}\x{13f8}-\x{13fd}\x{1401}-\x{167f}\x{1681}-\x{169a}\x{16a0}-\x{16f8}\x{1700}-\x{170c}\x{170e}-\x{1711}\x{1720}-\x{1731}\x{1735}\x{1736}\x{1740}-\x{1751}\x{1760}-\x{176c}\x{176e}-\x{1770}\x{1780}-\x{17b3}\x{17b6}\x{17be}-\x{17c5}\x{17c7}\x{17c8}\x{17d4}-\x{17da}\x{17dc}\x{17e0}-\x{17e9}\x{1810}-\x{1819}\x{1820}-\x{1877}\x{1880}-\x{18a8}\x{18aa}\x{18b0}-\x{18f5}\x{1900}-\x{191e}\x{1923}-\x{1926}\x{1929}-\x{192b}\x{1930}\x{1931}\x{1933}-\x{1938}\x{1946}-\x{196d}\x{1970}-\x{1974}\x{1980}-\x{19ab}\x{19b0}-\x{19c9}\x{19d0}-\x{19da}\x{1a00}-\x{1a16}\x{1a19}\x{1a1a}\x{1a1e}-\x{1a55}\x{1a57}\x{1a61}\x{1a63}\x{1a64}\x{1a6d}-\x{1a72}\x{1a80}-\x{1a89}\x{1a90}-\x{1a99}\x{1aa0}-\x{1aad}\x{1b04}-\x{1b33}\x{1b35}\x{1b3b}\x{1b3d}-\x{1b41}\x{1b43}-\x{1b4b}\x{1b50}-\x{1b6a}\x{1b74}-\x{1b7c}\x{1b82}-\x{1ba1}\x{1ba6}\x{1ba7}\x{1baa}\x{1bae}-\x{1be5}\x{1be7}\x{1bea}-\x{1bec}\x{1bee}\x{1bf2}\x{1bf3}\x{1bfc}-\x{1c2b}\x{1c34}\x{1c35}\x{1c3b}-\x{1c49}\x{1c4d}-\x{1c7f}\x{1cc0}-\x{1cc7}\x{1cd3}\x{1ce1}\x{1ce9}-\x{1cec}\x{1cee}-\x{1cf3}\x{1cf5}\x{1cf6}\x{1d00}-\x{1dbf}\x{1e00}-\x{1f15}\x{1f18}-\x{1f1d}\x{1f20}-\x{1f45}\x{1f48}-\x{1f4d}\x{1f50}-\x{1f57}\x{1f59}\x{1f5b}\x{1f5d}\x{1f5f}-\x{1f7d}\x{1f80}-\x{1fb4}\x{1fb6}-\x{1fbc}\x{1fbe}\x{1fc2}-\x{1fc4}\x{1fc6}-\x{1fcc}\x{1fd0}-\x{1fd3}\x{1fd6}-\x{1fdb}\x{1fe0}-\x{1fec}\x{1ff2}-\x{1ff4}\x{1ff6}-\x{1ffc}\x{200e}\x{2071}\x{207f}\x{2090}-\x{209c}\x{2102}\x{2107}\x{210a}-\x{2113}\x{2115}\x{2119}-\x{211d}\x{2124}\x{2126}\x{2128}\x{212a}-\x{212d}\x{212f}-\x{2139}\x{213c}-\x{213f}\x{2145}-\x{2149}\x{214e}\x{214f}\x{2160}-\x{2188}\x{2336}-\x{237a}\x{2395}\x{249c}-\x{24e9}\x{26ac}\x{2800}-\x{28ff}\x{2c00}-\x{2c2e}\x{2c30}-\x{2c5e}\x{2c60}-\x{2ce4}\x{2ceb}-\x{2cee}\x{2cf2}\x{2cf3}\x{2d00}-\x{2d25}\x{2d27}\x{2d2d}\x{2d30}-\x{2d67}\x{2d6f}\x{2d70}\x{2d80}-\x{2d96}\x{2da0}-\x{2da6}\x{2da8}-\x{2dae}\x{2db0}-\x{2db6}\x{2db8}-\x{2dbe}\x{2dc0}-\x{2dc6}\x{2dc8}-\x{2dce}\x{2dd0}-\x{2dd6}\x{2dd8}-\x{2dde}\x{3005}-\x{3007}\x{3021}-\x{3029}\x{302e}\x{302f}\x{3031}-\x{3035}\x{3038}-\x{303c}\x{3041}-\x{3096}\x{309d}-\x{309f}\x{30a1}-\x{30fa}\x{30fc}-\x{30ff}\x{3105}-\x{312d}\x{3131}-\x{318e}\x{3190}-\x{31ba}\x{31f0}-\x{321c}\x{3220}-\x{324f}\x{3260}-\x{327b}\x{327f}-\x{32b0}\x{32c0}-\x{32cb}\x{32d0}-\x{32fe}\x{3300}-\x{3376}\x{337b}-\x{33dd}\x{33e0}-\x{33fe}\x{3400}-\x{4db5}\x{4e00}-\x{9fd5}\x{a000}-\x{a48c}\x{a4d0}-\x{a60c}\x{a610}-\x{a62b}\x{a640}-\x{a66e}\x{a680}-\x{a69d}\x{a6a0}-\x{a6ef}\x{a6f2}-\x{a6f7}\x{a722}-\x{a787}\x{a789}-\x{a7ad}\x{a7b0}-\x{a7b7}\x{a7f7}-\x{a801}\x{a803}-\x{a805}\x{a807}-\x{a80a}\x{a80c}-\x{a824}\x{a827}\x{a830}-\x{a837}\x{a840}-\x{a873}\x{a880}-\x{a8c3}\x{a8ce}-\x{a8d9}\x{a8f2}-\x{a8fd}\x{a900}-\x{a925}\x{a92e}-\x{a946}\x{a952}\x{a953}\x{a95f}-\x{a97c}\x{a983}-\x{a9b2}\x{a9b4}\x{a9b5}\x{a9ba}\x{a9bb}\x{a9bd}-\x{a9cd}\x{a9cf}-\x{a9d9}\x{a9de}-\x{a9e4}\x{a9e6}-\x{a9fe}\x{aa00}-\x{aa28}\x{aa2f}\x{aa30}\x{aa33}\x{aa34}\x{aa40}-\x{aa42}\x{aa44}-\x{aa4b}\x{aa4d}\x{aa50}-\x{aa59}\x{aa5c}-\x{aa7b}\x{aa7d}-\x{aaaf}\x{aab1}\x{aab5}\x{aab6}\x{aab9}-\x{aabd}\x{aac0}\x{aac2}\x{aadb}-\x{aaeb}\x{aaee}-\x{aaf5}\x{ab01}-\x{ab06}\x{ab09}-\x{ab0e}\x{ab11}-\x{ab16}\x{ab20}-\x{ab26}\x{ab28}-\x{ab2e}\x{ab30}-\x{ab65}\x{ab70}-\x{abe4}\x{abe6}\x{abe7}\x{abe9}-\x{abec}\x{abf0}-\x{abf9}\x{ac00}-\x{d7a3}\x{d7b0}-\x{d7c6}\x{d7cb}-\x{d7fb}\x{e000}-\x{fa6d}\x{fa70}-\x{fad9}\x{fb00}-\x{fb06}\x{fb13}-\x{fb17}\x{ff21}-\x{ff3a}\x{ff41}-\x{ff5a}\x{ff66}-\x{ffbe}\x{ffc2}-\x{ffc7}\x{ffca}-\x{ffcf}\x{ffd2}-\x{ffd7}\x{ffda}-\x{ffdc}\x{10000}-\x{1000b}\x{1000d}-\x{10026}\x{10028}-\x{1003a}\x{1003c}\x{1003d}\x{1003f}-\x{1004d}\x{10050}-\x{1005d}\x{10080}-\x{100fa}\x{10100}\x{10102}\x{10107}-\x{10133}\x{10137}-\x{1013f}\x{101d0}-\x{101fc}\x{10280}-\x{1029c}\x{102a0}-\x{102d0}\x{10300}-\x{10323}\x{10330}-\x{1034a}\x{10350}-\x{10375}\x{10380}-\x{1039d}\x{1039f}-\x{103c3}\x{103c8}-\x{103d5}\x{10400}-\x{1049d}\x{104a0}-\x{104a9}\x{10500}-\x{10527}\x{10530}-\x{10563}\x{1056f}\x{10600}-\x{10736}\x{10740}-\x{10755}\x{10760}-\x{10767}\x{11000}\x{11002}-\x{11037}\x{11047}-\x{1104d}\x{11066}-\x{1106f}\x{11082}-\x{110b2}\x{110b7}\x{110b8}\x{110bb}-\x{110c1}\x{110d0}-\x{110e8}\x{110f0}-\x{110f9}\x{11103}-\x{11126}\x{1112c}\x{11136}-\x{11143}\x{11150}-\x{11172}\x{11174}-\x{11176}\x{11182}-\x{111b5}\x{111bf}-\x{111c9}\x{111cd}\x{111d0}-\x{111df}\x{111e1}-\x{111f4}\x{11200}-\x{11211}\x{11213}-\x{1122e}\x{11232}\x{11233}\x{11235}\x{11238}-\x{1123d}\x{11280}-\x{11286}\x{11288}\x{1128a}-\x{1128d}\x{1128f}-\x{1129d}\x{1129f}-\x{112a9}\x{112b0}-\x{112de}\x{112e0}-\x{112e2}\x{112f0}-\x{112f9}\x{11302}\x{11303}\x{11305}-\x{1130c}\x{1130f}\x{11310}\x{11313}-\x{11328}\x{1132a}-\x{11330}\x{11332}\x{11333}\x{11335}-\x{11339}\x{1133d}-\x{1133f}\x{11341}-\x{11344}\x{11347}\x{11348}\x{1134b}-\x{1134d}\x{11350}\x{11357}\x{1135d}-\x{11363}\x{11480}-\x{114b2}\x{114b9}\x{114bb}-\x{114be}\x{114c1}\x{114c4}-\x{114c7}\x{114d0}-\x{114d9}\x{11580}-\x{115b1}\x{115b8}-\x{115bb}\x{115be}\x{115c1}-\x{115db}\x{11600}-\x{11632}\x{1163b}\x{1163c}\x{1163e}\x{11641}-\x{11644}\x{11650}-\x{11659}\x{11680}-\x{116aa}\x{116ac}\x{116ae}\x{116af}\x{116b6}\x{116c0}-\x{116c9}\x{11700}-\x{11719}\x{11720}\x{11721}\x{11726}\x{11730}-\x{1173f}\x{118a0}-\x{118f2}\x{118ff}\x{11ac0}-\x{11af8}\x{12000}-\x{12399}\x{12400}-\x{1246e}\x{12470}-\x{12474}\x{12480}-\x{12543}\x{13000}-\x{1342e}\x{14400}-\x{14646}\x{16800}-\x{16a38}\x{16a40}-\x{16a5e}\x{16a60}-\x{16a69}\x{16a6e}\x{16a6f}\x{16ad0}-\x{16aed}\x{16af5}\x{16b00}-\x{16b2f}\x{16b37}-\x{16b45}\x{16b50}-\x{16b59}\x{16b5b}-\x{16b61}\x{16b63}-\x{16b77}\x{16b7d}-\x{16b8f}\x{16f00}-\x{16f44}\x{16f50}-\x{16f7e}\x{16f93}-\x{16f9f}\x{1b000}\x{1b001}\x{1bc00}-\x{1bc6a}\x{1bc70}-\x{1bc7c}\x{1bc80}-\x{1bc88}\x{1bc90}-\x{1bc99}\x{1bc9c}\x{1bc9f}\x{1d000}-\x{1d0f5}\x{1d100}-\x{1d126}\x{1d129}-\x{1d166}\x{1d16a}-\x{1d172}\x{1d183}\x{1d184}\x{1d18c}-\x{1d1a9}\x{1d1ae}-\x{1d1e8}\x{1d360}-\x{1d371}\x{1d400}-\x{1d454}\x{1d456}-\x{1d49c}\x{1d49e}\x{1d49f}\x{1d4a2}\x{1d4a5}\x{1d4a6}\x{1d4a9}-\x{1d4ac}\x{1d4ae}-\x{1d4b9}\x{1d4bb}\x{1d4bd}-\x{1d4c3}\x{1d4c5}-\x{1d505}\x{1d507}-\x{1d50a}\x{1d50d}-\x{1d514}\x{1d516}-\x{1d51c}\x{1d51e}-\x{1d539}\x{1d53b}-\x{1d53e}\x{1d540}-\x{1d544}\x{1d546}\x{1d54a}-\x{1d550}\x{1d552}-\x{1d6a5}\x{1d6a8}-\x{1d6da}\x{1d6dc}-\x{1d714}\x{1d716}-\x{1d74e}\x{1d750}-\x{1d788}\x{1d78a}-\x{1d7c2}\x{1d7c4}-\x{1d7cb}\x{1d800}-\x{1d9ff}\x{1da37}-\x{1da3a}\x{1da6d}-\x{1da74}\x{1da76}-\x{1da83}\x{1da85}-\x{1da8b}\x{1f110}-\x{1f12e}\x{1f130}-\x{1f169}\x{1f170}-\x{1f19a}\x{1f1e6}-\x{1f202}\x{1f210}-\x{1f23a}\x{1f240}-\x{1f248}\x{1f250}\x{1f251}\x{20000}-\x{2a6d6}\x{2a700}-\x{2b734}\x{2b740}-\x{2b81d}\x{2b820}-\x{2cea1}\x{2f800}-\x{2fa1d}\x{f0000}-\x{ffffd}\x{100000}-\x{10fffd}])|([\x{590}\x{5be}\x{5c0}\x{5c3}\x{5c6}\x{5c8}-\x{5ff}\x{7c0}-\x{7ea}\x{7f4}\x{7f5}\x{7fa}-\x{815}\x{81a}\x{824}\x{828}\x{82e}-\x{858}\x{85c}-\x{89f}\x{200f}\x{fb1d}\x{fb1f}-\x{fb28}\x{fb2a}-\x{fb4f}\x{10800}-\x{1091e}\x{10920}-\x{10a00}\x{10a04}\x{10a07}-\x{10a0b}\x{10a10}-\x{10a37}\x{10a3b}-\x{10a3e}\x{10a40}-\x{10ae4}\x{10ae7}-\x{10b38}\x{10b40}-\x{10e5f}\x{10e7f}-\x{10fff}\x{1e800}-\x{1e8cf}\x{1e8d7}-\x{1edff}\x{1ef00}-\x{1efff}\x{608}\x{60b}\x{60d}\x{61b}-\x{64a}\x{66d}-\x{66f}\x{671}-\x{6d5}\x{6e5}\x{6e6}\x{6ee}\x{6ef}\x{6fa}-\x{710}\x{712}-\x{72f}\x{74b}-\x{7a5}\x{7b1}-\x{7bf}\x{8a0}-\x{8e2}\x{fb50}-\x{fd3d}\x{fd40}-\x{fdcf}\x{fdf0}-\x{fdfc}\x{fdfe}\x{fdff}\x{fe70}-\x{fefe}\x{1ee00}-\x{1eeef}\x{1eef2}-\x{1eeff}]))/u';
182 if ( isset( $wgDummyLanguageCodes[
$code] ) ) {
183 $code = $wgDummyLanguageCodes[
$code];
187 $langObj = isset( self::$mLangObjCache[$code] )
188 ? self::$mLangObjCache[
$code]
189 : self::newFromCode( $code );
192 self::$mLangObjCache = array_merge( [ $code => $langObj ], self::$mLangObjCache );
194 self::$mLangObjCache = array_slice( self::$mLangObjCache, 0, $wgLangObjCacheSize,
true );
207 throw new MWException(
"Invalid language code \"$code\"" );
219 $class = self::classFromCode(
$code );
220 if ( class_exists( $class ) ) {
227 foreach ( $fallbacks
as $fallbackCode ) {
229 throw new MWException(
"Invalid fallback '$fallbackCode' in fallback sequence for '$code'" );
232 $class = self::classFromCode( $fallbackCode );
233 if ( class_exists( $class ) ) {
240 throw new MWException(
"Invalid fallback sequence for language '$code'" );
252 if ( !self::isValidBuiltInCode(
$code ) ) {
256 if (
$code ===
'qqq' ) {
260 return is_readable( self::getMessagesFileName(
$code ) ) ||
261 is_readable( self::getJsonMessagesFileName(
$code ) );
282 $alphanum =
'[a-z0-9]';
283 $x =
'x'; #
private use singleton
284 $singleton =
'[a-wy-z]'; #
other singleton
285 $s = $lenient ?
'[-_]' :
'-';
287 $language =
"$alpha{2,8}|$alpha{2,3}$s$alpha{3}";
288 $script =
"$alpha{4}"; # ISO 15924
289 $region =
"(?:$alpha{2}|$digit{3})"; # ISO 3166-1 alpha-2
or UN M.49
290 $variant =
"(?:$alphanum{5,8}|$digit$alphanum{3})";
291 $extension =
"$singleton(?:$s$alphanum{2,8})+";
292 $privateUse =
"$x(?:$s$alphanum{1,8})+";
294 # Define certain grandfathered codes, since otherwise the regex is pretty useless.
295 # Since these are limited, this is safe even later changes to the registry --
296 # the only oddity is that it might change the type of the tag, and thus
297 # the results from the capturing groups.
298 # http://www.iana.org/assignments/language-subtag-registry
300 $grandfathered =
"en{$s}GB{$s}oed"
301 .
"|i{$s}(?:ami|bnn|default|enochian|hak|klingon|lux|mingo|navajo|pwn|tao|tay|tsu)"
302 .
"|no{$s}(?:bok|nyn)"
303 .
"|sgn{$s}(?:BE{$s}(?:fr|nl)|CH{$s}de)"
304 .
"|zh{$s}min{$s}nan";
306 $variantList =
"$variant(?:$s$variant)*";
307 $extensionList =
"$extension(?:$s$extension)*";
309 $langtag =
"(?:($language)"
312 .
"(?:$s$variantList)?"
313 .
"(?:$s$extensionList)?"
314 .
"(?:$s$privateUse)?)";
316 # The final breakdown, with capturing groups for each of these components
317 # The variants, extensions, grandfathered, and private-use may have interior '-'
319 $root =
"^(?:$langtag|$privateUse|$grandfathered)$";
321 return (
bool)preg_match(
"/$root/", strtolower(
$code ) );
342 strcspn( $code,
":/\\\000&<>'\"" ) === strlen( $code )
360 if ( !is_string(
$code ) ) {
361 if ( is_object(
$code ) ) {
362 $addmsg =
" of class " . get_class(
$code );
367 throw new MWException( __METHOD__ .
" must be passed a string, $type given$addmsg" );
370 return (
bool)preg_match(
'/^[a-z0-9-]{2,}$/',
$code );
384 if ( !self::isValidBuiltInCode(
$tag ) ) {
389 || self::fetchLanguageName( $tag, $tag ) !==
''
403 if ( is_null( self::$dataCache ) ) {
405 $class = $wgLocalisationCacheConf[
'class'];
406 self::$dataCache =
new $class( $wgLocalisationCacheConf );
408 return self::$dataCache;
414 if ( get_class( $this ) ==
'Language' ) {
417 $this->mCode = str_replace(
'_',
'-', strtolower( substr( get_class( $this ), 8 ) ) );
419 self::getLocalisationCache();
427 unset( $this->
$name );
443 return self::getFallbacksFor( $this->mCode );
451 return self::$dataCache->getItem( $this->mCode,
'bookstoreList' );
461 if ( is_null( $this->namespaceNames ) ) {
464 $this->namespaceNames = self::$dataCache->getItem( $this->mCode,
'namespaceNames' );
467 $this->namespaceNames = $wgExtraNamespaces + $this->namespaceNames + $validNamespaces;
470 if ( $wgMetaNamespaceTalk ) {
478 # Sometimes a language will be localised but not actually exist on this wiki.
479 foreach ( $this->namespaceNames
as $key => $text ) {
480 if ( !isset( $validNamespaces[$key] ) ) {
481 unset( $this->namespaceNames[$key] );
485 # The above mixing may leave namespaces out of canonical order.
486 # Re-order by namespace ID number...
487 ksort( $this->namespaceNames );
489 Hooks::run(
'LanguageGetNamespaces', [ &$this->namespaceNames ] );
501 $this->mNamespaceIds = null;
508 $this->namespaceNames = null;
509 $this->mNamespaceIds = null;
510 $this->namespaceAliases = null;
521 foreach ( $ns
as $k => $v ) {
522 $ns[$k] = strtr( $v,
'_',
' ' );
540 return isset( $ns[$index] ) ? $ns[$index] :
false;
558 return strtr( $ns,
'_',
' ' );
572 $ns = $wgExtraGenderNamespaces +
573 (
array)self::$dataCache->getItem( $this->mCode,
'namespaceGenderAliases' );
575 return isset( $ns[$index][$gender] ) ? $ns[$index][$gender] : $this->
getNsText( $index );
586 if ( count( $wgExtraGenderNamespaces ) > 0 ) {
589 } elseif ( isset( $wgExtraNamespaces[
NS_USER] ) && isset( $wgExtraNamespaces[
NS_USER_TALK] ) ) {
595 $aliases = self::$dataCache->getItem( $this->mCode,
'namespaceGenderAliases' );
596 return count( $aliases ) > 0;
609 $lctext = $this->
lc( $text );
611 return isset( $ids[$lctext] ) ? $ids[$lctext] :
false;
618 if ( is_null( $this->namespaceAliases ) ) {
619 $aliases = self::$dataCache->getItem( $this->mCode,
'namespaceAliases' );
623 foreach ( $aliases
as $name => $index ) {
625 unset( $aliases[
$name] );
627 $aliases[
$name] = $index;
633 $genders = $wgExtraGenderNamespaces +
634 (
array)self::$dataCache->getItem( $this->mCode,
'namespaceGenderAliases' );
635 foreach ( $genders
as $index => $forms ) {
636 foreach ( $forms
as $alias ) {
637 $aliases[$alias] = $index;
641 # Also add converted namespace names as aliases, to avoid confusion.
642 $convertedNames = [];
644 if ( $variant === $this->mCode ) {
648 $convertedNames[$this->
getConverter()->convertNamespace( $ns, $variant )] = $ns;
652 $this->namespaceAliases = $aliases + $convertedNames;
662 if ( is_null( $this->mNamespaceIds ) ) {
664 # Put namespace names and aliases into a hashtable.
665 # If this is too slow, then we should arrange it so that it is done
666 # before caching. The catch is that at pre-cache time, the above
667 # class-specific fixup hasn't been done.
668 $this->mNamespaceIds = [];
670 $this->mNamespaceIds[$this->
lc(
$name )] = $index;
673 $this->mNamespaceIds[$this->
lc(
$name )] = $index;
675 if ( $wgNamespaceAliases ) {
676 foreach ( $wgNamespaceAliases
as $name => $index ) {
677 $this->mNamespaceIds[$this->
lc(
$name )] = $index;
692 $lctext = $this->
lc( $text );
694 if ( $ns !== null ) {
698 return isset( $ids[$lctext] ) ? $ids[$lctext] :
false;
709 $msg =
"variantname-$code";
710 if ( $usemsg &&
wfMessage( $msg )->exists() ) {
715 return $name; #
if it's defined as a language name, show that
717 # otherwise, output the language code
725 public function getDatePreferences() {
726 return self::$dataCache->getItem( $this->mCode, 'datePreferences
' );
732 function getDateFormats() {
733 return self::$dataCache->getItem( $this->mCode, 'dateFormats
' );
739 public function getDefaultDateFormat() {
740 $df = self::$dataCache->getItem( $this->mCode, 'defaultDateFormat
' );
741 if ( $df === 'dmy
or mdy
' ) {
742 global $wgAmericanDates;
743 return $wgAmericanDates ? 'mdy
' : 'dmy
';
752 public function getDatePreferenceMigrationMap() {
753 return self::$dataCache->getItem( $this->mCode, 'datePreferenceMigrationMap
' );
760 function getImageFile( $image ) {
761 return self::$dataCache->getSubitem( $this->mCode, 'imageFiles
', $image );
768 public function getImageFiles() {
769 return self::$dataCache->getItem( $this->mCode, 'imageFiles
' );
775 public function getExtraUserToggles() {
776 return (array)self::$dataCache->getItem( $this->mCode, 'extraUserToggles
' );
783 function getUserToggle( $tog ) {
784 return $this->getMessageFromDB( "tog-$tog" );
798 public static function fetchLanguageNames( $inLanguage = null, $include = 'mw
' ) {
799 $cacheKey = $inLanguage === null ? 'null
' : $inLanguage;
800 $cacheKey .= ":$include";
801 if ( self::$languageNameCache === null ) {
802 self::$languageNameCache = new HashBagOStuff( [ 'maxKeys
' => 20 ] );
805 $ret = self::$languageNameCache->get( $cacheKey );
807 $ret = self::fetchLanguageNamesUncached( $inLanguage, $include );
808 self::$languageNameCache->set( $cacheKey, $ret );
823 private static function fetchLanguageNamesUncached( $inLanguage = null, $include = 'mw
' ) {
824 global $wgExtraLanguageNames;
826 // If passed an invalid language code to use, fallback to en
827 if ( $inLanguage !== null && !Language::isValidCode( $inLanguage ) ) {
834 # TODO: also include when $inLanguage is null, when this code is more efficient
835 Hooks::run( 'LanguageGetTranslatedLanguageNames
', [ &$names, $inLanguage ] );
838 $mwNames = $wgExtraLanguageNames + MediaWiki\Languages\Data\Names::$names;
839 foreach ( $mwNames as $mwCode => $mwName ) {
840 # - Prefer own MediaWiki native name when not using the hook
841 # - For other names just add if not added through the hook
842 if ( $mwCode === $inLanguage || !isset( $names[$mwCode] ) ) {
843 $names[$mwCode] = $mwName;
847 if ( $include === 'all
' ) {
853 $coreCodes = array_keys( $mwNames );
854 foreach ( $coreCodes as $coreCode ) {
855 $returnMw[$coreCode] = $names[$coreCode];
858 if ( $include === 'mwfile
' ) {
860 # We do this using a foreach over the codes instead of a directory
861 # loop so that messages files in extensions will work correctly.
862 foreach ( $returnMw as $code => $value ) {
863 if ( is_readable( self::getMessagesFileName( $code ) )
864 || is_readable( self::getJsonMessagesFileName( $code ) )
866 $namesMwFile[$code] = $names[$code];
870 ksort( $namesMwFile );
887 $code = strtolower( $code );
888 $array = self::fetchLanguageNames( $inLanguage, $include );
889 return !array_key_exists( $code, $array ) ?
'' : $array[
$code];
899 return $this->
msg( $msg )->text();
908 protected function msg( $msg ) {
909 return wfMessage( $msg )->inLanguage( $this );
924 $monthNames = [
'' ];
925 for ( $i = 1; $i < 13; $i++ ) {
951 $monthNames = [
'' ];
952 for ( $i = 1; $i < 13; $i++ ) {
979 return $this->
getMessageFromDB( self::$mIranianCalendarMonthMsgs[$key - 1] );
987 return $this->
getMessageFromDB( self::$mHebrewCalendarMonthMsgs[$key - 1] );
995 return $this->
getMessageFromDB( self::$mHebrewCalendarMonthGenMsgs[$key - 1] );
1003 return $this->
getMessageFromDB( self::$mHijriCalendarMonthMsgs[$key - 1] );
1015 if ( !$dateTimeObj ) {
1016 $dateTimeObj = DateTime::createFromFormat(
1017 'YmdHis', $ts, $zone ?:
new DateTimeZone(
'UTC' )
1020 return $dateTimeObj->format(
$code );
1090 public function sprintfDate( $format, $ts, DateTimeZone $zone = null, &$ttl =
'unused' ) {
1095 $dateTimeObj =
false;
1104 $usedSecond =
false;
1105 $usedMinute =
false;
1112 $usedISOYear =
false;
1113 $usedIsLeapYear =
false;
1115 $usedHebrewMonth =
false;
1116 $usedIranianMonth =
false;
1117 $usedHijriMonth =
false;
1118 $usedHebrewYear =
false;
1119 $usedIranianYear =
false;
1120 $usedHijriYear =
false;
1121 $usedTennoYear =
false;
1123 if ( strlen( $ts ) !== 14 ) {
1124 throw new MWException( __METHOD__ .
": The timestamp $ts should have 14 characters" );
1127 if ( !ctype_digit( $ts ) ) {
1128 throw new MWException( __METHOD__ .
": The timestamp $ts should be a number" );
1131 $formatLength = strlen( $format );
1132 for ( $p = 0; $p < $formatLength; $p++ ) {
1134 $code = $format[$p];
1135 if (
$code ==
'x' && $p < $formatLength - 1 ) {
1136 $code .= $format[++$p];
1139 if ( (
$code ===
'xi'
1145 && $p < $formatLength - 1 ) {
1146 $code .= $format[++$p];
1157 $rawToggle = !$rawToggle;
1170 $usedHebrewMonth =
true;
1172 $hebrew = self::tsToHebrew( $ts );
1178 $num = substr( $ts, 6, 2 );
1188 $num = intval( substr( $ts, 6, 2 ) );
1193 $iranian = self::tsToIranian( $ts );
1200 $hijri = self::tsToHijri( $ts );
1207 $hebrew = self::tsToHebrew( $ts );
1222 $usedIranianMonth =
true;
1224 $iranian = self::tsToIranian( $ts );
1229 $usedHijriMonth =
true;
1231 $hijri = self::tsToHijri( $ts );
1236 $usedHebrewMonth =
true;
1238 $hebrew = self::tsToHebrew( $ts );
1244 $num = substr( $ts, 4, 2 );
1252 $num = intval( substr( $ts, 4, 2 ) );
1255 $usedIranianMonth =
true;
1257 $iranian = self::tsToIranian( $ts );
1262 $usedHijriMonth =
true;
1264 $hijri = self::tsToHijri( $ts );
1269 $usedHebrewMonth =
true;
1271 $hebrew = self::tsToHebrew( $ts );
1276 $usedHebrewMonth =
true;
1278 $hebrew = self::tsToHebrew( $ts );
1284 $num = substr( $ts, 0, 4 );
1287 $usedIranianYear =
true;
1289 $iranian = self::tsToIranian( $ts );
1294 $usedHijriYear =
true;
1296 $hijri = self::tsToHijri( $ts );
1301 $usedHebrewYear =
true;
1303 $hebrew = self::tsToHebrew( $ts );
1310 $thai = self::tsToYear( $ts,
'thai' );
1317 $minguo = self::tsToYear( $ts,
'minguo' );
1322 $usedTennoYear =
true;
1324 $tenno = self::tsToYear( $ts,
'tenno' );
1330 $num = substr( $ts, 2, 2 );
1333 $usedIranianYear =
true;
1335 $iranian = self::tsToIranian( $ts );
1337 $num = substr( $iranian[0], -2 );
1341 $s .= intval( substr( $ts, 8, 2 ) ) < 12 ?
'am' :
'pm';
1345 $s .= intval( substr( $ts, 8, 2 ) ) < 12 ?
'AM' :
'PM';
1349 $h = substr( $ts, 8, 2 );
1350 $num = $h % 12 ? $h % 12 : 12;
1354 $num = intval( substr( $ts, 8, 2 ) );
1358 $h = substr( $ts, 8, 2 );
1359 $num = sprintf(
'%02d', $h % 12 ? $h % 12 : 12 );
1363 $num = substr( $ts, 8, 2 );
1367 $num = substr( $ts, 10, 2 );
1371 $num = substr( $ts, 12, 2 );
1398 $usedIsLeapYear =
true;
1402 $usedISOYear =
true;
1413 # Backslash escaping
1414 if ( $p < $formatLength - 1 ) {
1415 $s .= $format[++$p];
1422 if ( $p < $formatLength - 1 ) {
1423 $endQuote = strpos( $format,
'"', $p + 1 );
1424 if ( $endQuote ===
false ) {
1425 # No terminating quote, assume literal "
1428 $s .= substr( $format, $p + 1, $endQuote - $p - 1 );
1432 # Quote at end of string, assume literal "
1439 if ( $num !==
false ) {
1440 if ( $rawToggle || $raw ) {
1443 } elseif ( $roman ) {
1446 } elseif ( $hebrewNum ) {
1447 $s .= self::hebrewNumeral( $num );
1455 if ( $ttl ===
'unused' ) {
1457 } elseif ( $usedSecond ) {
1459 } elseif ( $usedMinute ) {
1460 $ttl = 60 - substr( $ts, 12, 2 );
1461 } elseif ( $usedHour ) {
1462 $ttl = 3600 - substr( $ts, 10, 2 ) * 60 - substr( $ts, 12, 2 );
1463 } elseif ( $usedAMPM ) {
1464 $ttl = 43200 - ( substr( $ts, 8, 2 ) % 12 ) * 3600 -
1465 substr( $ts, 10, 2 ) * 60 - substr( $ts, 12, 2 );
1469 $usedIranianMonth ||
1478 $ttl = 86400 - substr( $ts, 8, 2 ) * 3600 -
1479 substr( $ts, 10, 2 ) * 60 - substr( $ts, 12, 2 );
1482 $timeRemainingInDay = 86400 - substr( $ts, 8, 2 ) * 3600 -
1483 substr( $ts, 10, 2 ) * 60 - substr( $ts, 12, 2 );
1487 $timeRemainingInDay;
1488 } elseif ( $usedISOYear ) {
1491 $lastWeekOfISOYear = DateTime::createFromFormat(
1493 substr( $ts, 0, 4 ) .
'1228',
1494 $zone ?:
new DateTimeZone(
'UTC' )
1497 $weeksRemaining = $lastWeekOfISOYear - $currentISOWeek;
1498 $timeRemainingInWeek =
1500 + $timeRemainingInDay;
1501 $possibleTtls[] = $weeksRemaining * 604800 + $timeRemainingInWeek;
1507 substr( $ts, 6, 2 ) ) * 86400
1508 + $timeRemainingInDay;
1509 } elseif ( $usedYear ) {
1513 + $timeRemainingInDay;
1514 } elseif ( $usedIsLeapYear ) {
1515 $year = substr( $ts, 0, 4 );
1516 $timeRemainingInYear =
1519 + $timeRemainingInDay;
1521 if ( $mod || ( !( $year % 100 ) && $year % 400 ) ) {
1523 $nextCandidate = $year - $mod + 4;
1524 if ( $nextCandidate % 100 || !( $nextCandidate % 400 ) ) {
1525 $possibleTtls[] = ( $nextCandidate - $year - 1 ) * 365 * 86400 +
1526 $timeRemainingInYear;
1528 $possibleTtls[] = ( $nextCandidate - $year + 3 ) * 365 * 86400 +
1529 $timeRemainingInYear;
1533 $possibleTtls[] = $timeRemainingInYear;
1537 if ( $possibleTtls ) {
1538 $ttl = min( $possibleTtls );
1545 private static $GREG_DAYS = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
1546 private static $IRANIAN_DAYS = [ 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 ];
1561 $gy = substr( $ts, 0, 4 ) -1600;
1562 $gm = substr( $ts, 4, 2 ) -1;
1563 $gd = substr( $ts, 6, 2 ) -1;
1565 # Days passed from the beginning (including leap years)
1567 + floor( ( $gy + 3 ) / 4 )
1568 - floor( ( $gy + 99 ) / 100 )
1569 + floor( ( $gy + 399 ) / 400 );
1572 for ( $i = 0; $i < $gm; $i++ ) {
1573 $gDayNo += self::$GREG_DAYS[$i];
1577 if ( $gm > 1 && ( ( $gy % 4 === 0 && $gy % 100 !== 0 || ( $gy % 400 == 0 ) ) ) ) {
1582 $gDayNo += (int)$gd;
1584 $jDayNo = $gDayNo - 79;
1586 $jNp = floor( $jDayNo / 12053 );
1589 $jy = 979 + 33 * $jNp + 4 * floor( $jDayNo / 1461 );
1592 if ( $jDayNo >= 366 ) {
1593 $jy += floor( ( $jDayNo - 1 ) / 365 );
1594 $jDayNo = floor( ( $jDayNo - 1 ) % 365 );
1597 for ( $i = 0; $i < 11 && $jDayNo >= self::$IRANIAN_DAYS[$i]; $i++ ) {
1598 $jDayNo -= self::$IRANIAN_DAYS[$i];
1604 return [ $jy, $jm, $jd ];
1619 $year = substr( $ts, 0, 4 );
1620 $month = substr( $ts, 4, 2 );
1621 $day = substr( $ts, 6, 2 );
1629 ( $zy > 1582 ) || ( ( $zy == 1582 ) && ( $zm > 10 ) ) ||
1630 ( ( $zy == 1582 ) && ( $zm == 10 ) && ( $zd > 14 ) )
1632 $zjd = (int)( ( 1461 * ( $zy + 4800 + (
int)( ( $zm - 14 ) / 12 ) ) ) / 4 ) +
1633 (
int)( ( 367 * ( $zm - 2 - 12 * ( (int)( ( $zm - 14 ) / 12 ) ) ) ) / 12 ) -
1634 (
int)( ( 3 * (int)( ( ( $zy + 4900 + (
int)( ( $zm - 14 ) / 12 ) ) / 100 ) ) ) / 4 ) +
1637 $zjd = 367 * $zy - (int)( ( 7 * ( $zy + 5001 + (
int)( ( $zm - 9 ) / 7 ) ) ) / 4 ) +
1638 (
int)( ( 275 * $zm ) / 9 ) + $zd + 1729777;
1641 $zl = $zjd -1948440 + 10632;
1642 $zn = (int)( ( $zl - 1 ) / 10631 );
1643 $zl = $zl - 10631 * $zn + 354;
1644 $zj = ( (int)( ( 10985 - $zl ) / 5316 ) ) * ( (int)( ( 50 * $zl ) / 17719 ) ) +
1645 ( (int)( $zl / 5670 ) ) * ( (
int)( ( 43 * $zl ) / 15238 ) );
1646 $zl = $zl - ( (int)( ( 30 - $zj ) / 15 ) ) * ( (int)( ( 17719 * $zj ) / 50 ) ) -
1647 ( (int)( $zj / 16 ) ) * ( (
int)( ( 15238 * $zj ) / 43 ) ) + 29;
1648 $zm = (int)( ( 24 * $zl ) / 709 );
1649 $zd = $zl - (int)( ( 709 * $zm ) / 24 );
1650 $zy = 30 * $zn + $zj - 30;
1652 return [ $zy, $zm, $zd ];
1672 $year = substr( $ts, 0, 4 );
1673 $month = substr( $ts, 4, 2 );
1674 $day = substr( $ts, 6, 2 );
1676 # Calculate Hebrew year
1677 $hebrewYear = $year + 3760;
1679 # Month number when September = 1, August = 12
1681 if ( $month > 12 ) {
1688 # Calculate day of year from 1 September
1690 for ( $i = 1; $i < $month; $i++ ) {
1694 # Check if the year is leap
1695 if ( $year % 400 == 0 || ( $year % 4 == 0 && $year % 100 > 0 ) ) {
1698 } elseif ( $i == 8 || $i == 10 || $i == 1 || $i == 3 ) {
1705 # Calculate the start of the Hebrew year
1706 $start = self::hebrewYearStart( $hebrewYear );
1708 # Calculate next year's start
1709 if ( $dayOfYear <= $start ) {
1710 # Day is before the start of the year - it is the previous year
1712 $nextStart = $start;
1716 # Add days since previous year's 1 September
1718 if ( ( $year % 400 == 0 ) || ( $year % 100 != 0 && $year % 4 == 0 ) ) {
1722 # Start of the new (previous) year
1723 $start = self::hebrewYearStart( $hebrewYear );
1726 $nextStart = self::hebrewYearStart( $hebrewYear + 1 );
1729 # Calculate Hebrew day of year
1730 $hebrewDayOfYear = $dayOfYear - $start;
1732 # Difference between year's days
1733 $diff = $nextStart - $start;
1734 # Add 12 (or 13 for leap years) days to ignore the difference between
1735 # Hebrew and Gregorian year (353 at least vs. 365/6) - now the
1736 # difference is only about the year type
1737 if ( ( $year % 400 == 0 ) || ( $year % 100 != 0 && $year % 4 == 0 ) ) {
1743 # Check the year pattern, and is leap year
1744 # 0 means an incomplete year, 1 means a regular year, 2 means a complete year
1745 # This is mod 30, to work on both leap years (which add 30 days of Adar I)
1746 # and non-leap years
1747 $yearPattern = $diff % 30;
1748 # Check if leap year
1749 $isLeap = $diff >= 30;
1751 # Calculate day in the month from number of day in the Hebrew year
1752 # Don't check Adar - if the day is not in Adar, we will stop before;
1753 # if it is in Adar, we will use it to check if it is Adar I or Adar II
1754 $hebrewDay = $hebrewDayOfYear;
1757 while ( $hebrewMonth <= 12 ) {
1758 # Calculate days in this month
1759 if ( $isLeap && $hebrewMonth == 6 ) {
1760 # Adar in a leap year
1762 # Leap year - has Adar I, with 30 days, and Adar II, with 29 days
1764 if ( $hebrewDay <= $days ) {
1768 # Subtract the days of Adar I
1769 $hebrewDay -= $days;
1772 if ( $hebrewDay <= $days ) {
1778 } elseif ( $hebrewMonth == 2 && $yearPattern == 2 ) {
1779 # Cheshvan in a complete year (otherwise as the rule below)
1781 } elseif ( $hebrewMonth == 3 && $yearPattern == 0 ) {
1782 # Kislev in an incomplete year (otherwise as the rule below)
1785 # Odd months have 30 days, even have 29
1786 $days = 30 - ( $hebrewMonth - 1 ) % 2;
1788 if ( $hebrewDay <= $days ) {
1789 # In the current month
1792 # Subtract the days of the current month
1793 $hebrewDay -= $days;
1794 # Try in the next month
1799 return [ $hebrewYear, $hebrewMonth, $hebrewDay, $days ];
1812 $a = intval( ( 12 * ( $year - 1 ) + 17 ) % 19 );
1813 $b = intval( ( $year - 1 ) % 4 );
1814 $m = 32.044093161144 + 1.5542417966212 * $a + $b / 4.0 - 0.0031777940220923 * ( $year - 1 );
1818 $Mar = intval( $m );
1824 $c = intval( ( $Mar + 3 * ( $year - 1 ) + 5 * $b + 5 ) % 7 );
1825 if ( $c == 0 && $a > 11 && $m >= 0.89772376543210 ) {
1827 } elseif ( $c == 1 && $a > 6 && $m >= 0.63287037037037 ) {
1829 } elseif ( $c == 2 || $c == 4 || $c == 6 ) {
1833 $Mar += intval( ( $year - 3761 ) / 100 ) - intval( ( $year - 3761 ) / 400 ) - 24;
1850 $gy = substr( $ts, 0, 4 );
1851 $gm = substr( $ts, 4, 2 );
1852 $gd = substr( $ts, 6, 2 );
1854 if ( !strcmp( $cName,
'thai' ) ) {
1856 # Add 543 years to the Gregorian calendar
1857 # Months and days are identical
1858 $gy_offset = $gy + 543;
1859 } elseif ( ( !strcmp( $cName,
'minguo' ) ) || !strcmp( $cName,
'juche' ) ) {
1861 # Deduct 1911 years from the Gregorian calendar
1862 # Months and days are identical
1863 $gy_offset = $gy - 1911;
1864 } elseif ( !strcmp( $cName,
'tenno' ) ) {
1865 # Nengō dates up to Meiji period
1866 # Deduct years from the Gregorian calendar
1867 # depending on the nengo periods
1868 # Months and days are identical
1870 || ( ( $gy == 1912 ) && ( $gm < 7 ) )
1871 || ( ( $gy == 1912 ) && ( $gm == 7 ) && ( $gd < 31 ) )
1874 $gy_gannen = $gy - 1868 + 1;
1875 $gy_offset = $gy_gannen;
1876 if ( $gy_gannen == 1 ) {
1879 $gy_offset =
'明治' . $gy_offset;
1881 ( ( $gy == 1912 ) && ( $gm == 7 ) && ( $gd == 31 ) ) ||
1882 ( ( $gy == 1912 ) && ( $gm >= 8 ) ) ||
1883 ( ( $gy > 1912 ) && ( $gy < 1926 ) ) ||
1884 ( ( $gy == 1926 ) && ( $gm < 12 ) ) ||
1885 ( ( $gy == 1926 ) && ( $gm == 12 ) && ( $gd < 26 ) )
1888 $gy_gannen = $gy - 1912 + 1;
1889 $gy_offset = $gy_gannen;
1890 if ( $gy_gannen == 1 ) {
1893 $gy_offset =
'大正' . $gy_offset;
1895 ( ( $gy == 1926 ) && ( $gm == 12 ) && ( $gd >= 26 ) ) ||
1896 ( ( $gy > 1926 ) && ( $gy < 1989 ) ) ||
1897 ( ( $gy == 1989 ) && ( $gm == 1 ) && ( $gd < 8 ) )
1900 $gy_gannen = $gy - 1926 + 1;
1901 $gy_offset = $gy_gannen;
1902 if ( $gy_gannen == 1 ) {
1905 $gy_offset =
'昭和' . $gy_offset;
1908 $gy_gannen = $gy - 1989 + 1;
1909 $gy_offset = $gy_gannen;
1910 if ( $gy_gannen == 1 ) {
1913 $gy_offset =
'平成' . $gy_offset;
1919 return [ $gy_offset, $gm, $gd ];
1936 if ( !preg_match( self::$strongDirRegex, $text,
$matches ) ) {
1954 [
'',
'I',
'II',
'III',
'IV',
'V',
'VI',
'VII',
'VIII',
'IX',
'X' ],
1955 [
'',
'X',
'XX',
'XXX',
'XL',
'L',
'LX',
'LXX',
'LXXX',
'XC',
'C' ],
1956 [
'',
'C',
'CC',
'CCC',
'CD',
'D',
'DC',
'DCC',
'DCCC',
'CM',
'M' ],
1957 [
'',
'M',
'MM',
'MMM',
'MMMM',
'MMMMM',
'MMMMMM',
'MMMMMMM',
1958 'MMMMMMMM',
'MMMMMMMMM',
'MMMMMMMMMM' ]
1961 $num = intval( $num );
1962 if ( $num > 10000 || $num <= 0 ) {
1967 for ( $pow10 = 1000, $i = 3; $i >= 0; $pow10 /= 10, $i-- ) {
1968 if ( $num >= $pow10 ) {
1969 $s .= $table[$i][(int)floor( $num / $pow10 )];
1971 $num = $num % $pow10;
1985 [
'',
'א',
'ב',
'ג',
'ד',
'ה',
'ו',
'ז',
'ח',
'ט',
'י' ],
1986 [
'',
'י',
'כ',
'ל',
'מ',
'נ',
'ס',
'ע',
'פ',
'צ',
'ק' ],
1999 [
'',
'א',
'ב',
'ג',
'ד',
'ה',
'ו',
'ז',
'ח',
'ט',
'י' ]
2002 $num = intval( $num );
2003 if ( $num > 9999 || $num <= 0 ) {
2008 if ( $num === 1000 ) {
2010 } elseif ( $num % 1000 === 0 ) {
2011 return $table[0][$num / 1000] .
"' אלפים";
2016 for ( $pow10 = 1000, $i = 3; $i >= 0; $pow10 /= 10, $i-- ) {
2017 if ( $num >= $pow10 ) {
2018 if ( $num === 15 || $num === 16 ) {
2019 $letters[] = $table[0][9];
2020 $letters[] = $table[0][$num - 9];
2023 $letters = array_merge(
2025 (
array)$table[$i][intval( $num / $pow10 )]
2028 if ( $pow10 === 1000 ) {
2034 $num = $num % $pow10;
2037 $preTransformLength = count( $letters );
2038 if ( $preTransformLength === 1 ) {
2042 $lastIndex = $preTransformLength - 1;
2043 $letters[$lastIndex] = str_replace(
2044 [
'כ',
'מ',
'נ',
'פ',
'צ' ],
2045 [
'ך',
'ם',
'ן',
'ף',
'ץ' ],
2046 $letters[$lastIndex]
2052 if ( $letters[1] ===
"'" && $preTransformLength === 3 ) {
2055 array_splice( $letters, -1, 0,
'"' );
2059 return implode( $letters );
2073 if ( $tz ===
false ) {
2074 $tz = $wgUser->getOption(
'timecorrection' );
2077 $data = explode(
'|', $tz, 3 );
2079 if ( $data[0] ==
'ZoneInfo' ) {
2080 MediaWiki\suppressWarnings();
2081 $userTZ = timezone_open( $data[2] );
2082 MediaWiki\restoreWarnings();
2083 if ( $userTZ !==
false ) {
2084 $date = date_create( $ts, timezone_open(
'UTC' ) );
2085 date_timezone_set( $date, $userTZ );
2086 $date = date_format( $date,
'YmdHis' );
2089 # Unrecognized timezone, default to 'Offset' with the stored offset.
2090 $data[0] =
'Offset';
2093 if ( $data[0] ==
'System' || $tz ==
'' ) {
2094 # Global offset in minutes.
2096 } elseif ( $data[0] ==
'Offset' ) {
2097 $minDiff = intval( $data[1] );
2099 $data = explode(
':', $tz );
2100 if ( count( $data ) == 2 ) {
2101 $data[0] = intval( $data[0] );
2102 $data[1] = intval( $data[1] );
2103 $minDiff = abs( $data[0] ) * 60 + $data[1];
2104 if ( $data[0] < 0 ) {
2105 $minDiff = -$minDiff;
2108 $minDiff = intval( $data[0] ) * 60;
2112 # No difference ? Return time unchanged
2113 if ( 0 == $minDiff ) {
2117 MediaWiki\suppressWarnings();
2118 # Generate an adjusted date; take advantage of the fact that mktime
2119 # will normalize out-of-range values so we don't have to split $minDiff
2120 # into hours and minutes.
2122 (
int)substr( $ts, 8, 2 ) ), # Hours
2123 (
int)substr( $ts, 10, 2 ) + $minDiff, # Minutes
2124 (
int)substr( $ts, 12, 2 ), # Seconds
2125 (
int)substr( $ts, 4, 2 ), # Month
2126 (
int)substr( $ts, 6, 2 ), # Day
2127 (
int)substr( $ts, 0, 4 ) ); # Year
2129 $date =
date(
'YmdHis',
$t );
2130 MediaWiki\restoreWarnings();
2155 if ( is_bool( $usePrefs ) ) {
2157 $datePreference = $wgUser->getDatePreference();
2162 $datePreference = (
string)$usePrefs;
2166 if ( $datePreference ==
'' ) {
2170 return $datePreference;
2184 $wasDefault =
false;
2185 if ( $pref ==
'default' ) {
2190 if ( !isset( $this->dateFormatStrings[
$type][$pref] ) ) {
2191 $df = self::$dataCache->getSubitem( $this->mCode,
'dateFormats',
"$pref $type" );
2193 if (
$type ===
'pretty' && $df === null ) {
2197 if ( !$wasDefault && $df === null ) {
2199 $df = self::$dataCache->getSubitem( $this->mCode,
'dateFormats',
"$pref $type" );
2202 $this->dateFormatStrings[
$type][$pref] = $df;
2204 return $this->dateFormatStrings[
$type][$pref];
2217 public function date( $ts, $adj =
false, $format =
true, $timecorrection =
false ) {
2220 $ts = $this->
userAdjust( $ts, $timecorrection );
2236 public function time( $ts, $adj =
false, $format =
true, $timecorrection =
false ) {
2239 $ts = $this->
userAdjust( $ts, $timecorrection );
2256 public function timeanddate( $ts, $adj =
false, $format =
true, $timecorrection =
false ) {
2259 $ts = $this->
userAdjust( $ts, $timecorrection );
2280 foreach ( $intervals
as $intervalName => $intervalValue ) {
2283 $message =
wfMessage(
'duration-' . $intervalName )->numParams( $intervalValue );
2284 $segments[] = $message->inLanguage( $this )->escaped();
2302 if ( empty( $chosenIntervals ) ) {
2303 $chosenIntervals = [
2315 $intervals = array_intersect_key( self::$durationIntervals, array_flip( $chosenIntervals ) );
2316 $sortedNames = array_keys( $intervals );
2317 $smallestInterval = array_pop( $sortedNames );
2321 foreach ( $intervals
as $name => $length ) {
2322 $value = floor( $seconds / $length );
2324 if (
$value > 0 || (
$name == $smallestInterval && empty( $segments ) ) ) {
2325 $seconds -=
$value * $length;
2354 $options += [
'timecorrection' =>
true,
'format' =>
true ];
2355 if ( $options[
'timecorrection'] !==
false ) {
2356 if ( $options[
'timecorrection'] ===
true ) {
2357 $offset = $user->
getOption(
'timecorrection' );
2359 $offset = $options[
'timecorrection'];
2363 if ( $options[
'format'] ===
true ) {
2366 $format = $options[
'format'];
2459 if ( $relativeTo === null ) {
2462 if (
$user === null ) {
2468 $offsetRel = $relativeTo->offsetForUser(
$user );
2471 if (
Hooks::run(
'GetHumanTimestamp', [ &$ts, $time, $relativeTo,
$user, $this ] ) ) {
2476 $time->timestamp->sub( $offsetThis );
2477 $relativeTo->timestamp->sub( $offsetRel );
2496 $diff = $ts->
diff( $relativeTo );
2497 $diffDay = (bool)( (
int)$ts->timestamp->
format(
'w' ) -
2498 (int)$relativeTo->timestamp->
format(
'w' ) );
2499 $days = $diff->days ?: (int)$diffDay;
2500 if ( $diff->invert || $days > 5
2501 && $ts->timestamp->
format(
'Y' ) !== $relativeTo->timestamp->
format(
'Y' )
2510 } elseif ( $days > 5 ) {
2514 } elseif ( $days > 1 ) {
2517 $weekday = self::$mWeekdayMsgs[$ts->timestamp->
format(
'w' )];
2521 ->inLanguage( $this )
2524 } elseif ( $days == 1 ) {
2528 ->inLanguage( $this )
2531 } elseif ( $diff->h > 1 || $diff->h == 1 && $diff->i > 30 ) {
2535 ->inLanguage( $this )
2541 } elseif ( $diff->h == 1 ) {
2543 $ts =
wfMessage(
'hours-ago' )->inLanguage( $this )->numParams( 1 )->text();
2544 } elseif ( $diff->i >= 1 ) {
2546 $ts =
wfMessage(
'minutes-ago' )->inLanguage( $this )->numParams( $diff->i )->text();
2547 } elseif ( $diff->s >= 30 ) {
2549 $ts =
wfMessage(
'seconds-ago' )->inLanguage( $this )->numParams( $diff->s )->text();
2563 return self::$dataCache->getSubitem( $this->mCode,
'messages', $key );
2570 return self::$dataCache->getItem( $this->mCode,
'messages' );
2580 # Even with //IGNORE iconv can whine about illegal characters in
2581 # *input* string. We just ignore those too.
2582 # REF: http://bugs.php.net/bug.php?id=37166
2583 # REF: https://phabricator.wikimedia.org/T18885
2584 MediaWiki\suppressWarnings();
2585 $text =
iconv( $in,
$out .
'//IGNORE', $string );
2586 MediaWiki\restoreWarnings();
2605 return mb_strtoupper(
$matches[0] );
2613 return mb_strtoupper(
$matches[0] );
2627 } elseif ( $o < 128 ) {
2631 return $this->
uc( $str,
true );
2643 public function uc( $str, $first =
false ) {
2646 return mb_strtoupper( mb_substr( $str, 0, 1 ) ) . mb_substr( $str, 1 );
2651 return $this->
isMultibyte( $str ) ? mb_strtoupper( $str ) : strtoupper( $str );
2662 return strval( $str );
2663 } elseif ( $o >= 128 ) {
2664 return $this->
lc( $str,
true );
2665 } elseif ( $o > 96 ) {
2668 $str[0] = strtolower( $str[0] );
2678 function lc( $str, $first =
false ) {
2681 return mb_strtolower( mb_substr( $str, 0, 1 ) ) . mb_substr( $str, 1 );
2683 return strtolower( substr( $str, 0, 1 ) ) . substr( $str, 1 );
2686 return $this->
isMultibyte( $str ) ? mb_strtolower( $str ) : strtolower( $str );
2695 return strlen( $str ) !== mb_strlen( $str );
2704 $str = $this->
lc( $str );
2707 $replaceRegexp =
"/^([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)| ([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)/";
2710 return preg_replace_callback(
2712 [ $this,
'ucwordsCallbackMB' ],
2716 return ucwords( strtolower( $str ) );
2728 $str = $this->
lc( $str );
2731 $breaks =
"[ \-\(\)\}\{\.,\?!]";
2734 $replaceRegexp =
"/^([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)|" .
2735 "$breaks([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)/";
2737 return preg_replace_callback(
2739 [ $this,
'ucwordbreaksCallbackMB' ],
2743 return preg_replace_callback(
2744 '/\b([\w\x80-\xff]+)\b/',
2745 [ $this,
'ucwordbreaksCallbackAscii' ],
2767 return $this->
uc(
$s );
2776 if ( is_array(
$s ) ) {
2777 throw new MWException(
'Given array to checkTitleEncoding.' );
2779 if ( StringUtils::isUtf8(
$s ) ) {
2790 return self::$dataCache->getItem( $this->mCode,
'fallback8bitEncoding' );
2824 return self::convertDoubleWidth( $string );
2836 static $full = null;
2837 static $half = null;
2839 if ( $full === null ) {
2840 $fullWidth =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2841 $halfWidth =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2842 $full = str_split( $fullWidth, 3 );
2843 $half = str_split( $halfWidth );
2846 $string = str_replace( $full, $half, $string );
2856 $string = preg_replace( $pattern,
" $1 ", $string );
2857 $string = preg_replace(
'/ +/',
' ', $string );
2866 # some languages, e.g. Chinese, need to do a conversion
2867 # in order for search results to be displayed correctly
2880 '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
2881 '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})/',
2887 if ( strlen(
$matches[1] ) != 3 ) {
2895 } elseif (
$code < 0xb098 ) {
2896 return "\xe3\x84\xb1";
2897 } elseif (
$code < 0xb2e4 ) {
2898 return "\xe3\x84\xb4";
2899 } elseif (
$code < 0xb77c ) {
2900 return "\xe3\x84\xb7";
2901 } elseif (
$code < 0xb9c8 ) {
2902 return "\xe3\x84\xb9";
2903 } elseif (
$code < 0xbc14 ) {
2904 return "\xe3\x85\x81";
2905 } elseif (
$code < 0xc0ac ) {
2906 return "\xe3\x85\x82";
2907 } elseif (
$code < 0xc544 ) {
2908 return "\xe3\x85\x85";
2909 } elseif (
$code < 0xc790 ) {
2910 return "\xe3\x85\x87";
2911 } elseif (
$code < 0xcc28 ) {
2912 return "\xe3\x85\x88";
2913 } elseif (
$code < 0xce74 ) {
2914 return "\xe3\x85\x8a";
2915 } elseif (
$code < 0xd0c0 ) {
2916 return "\xe3\x85\x8b";
2917 } elseif (
$code < 0xd30c ) {
2918 return "\xe3\x85\x8c";
2919 } elseif (
$code < 0xd558 ) {
2920 return "\xe3\x85\x8d";
2922 return "\xe3\x85\x8e";
2967 $s = UtfNormal\Validator::cleanUp(
$s );
2968 if ( $wgAllUnicodeFixes ) {
2991 if ( !isset( $this->transformData[$file] ) ) {
2993 if ( $data ===
false ) {
2994 throw new MWException( __METHOD__ .
": The transformation file $file is missing" );
2998 return $this->transformData[$file]->replace( $string );
3007 return self::$dataCache->getItem( $this->mCode,
'rtl' );
3015 return $this->
isRTL() ?
'rtl' :
'ltr';
3027 return $this->
isRTL() ?
'right' :
'left';
3039 return $this->
isRTL() ?
'left' :
'right';
3055 return $this->
isRTL() ?
'‎' :
'‏';
3057 return $this->
isRTL() ?
'‏' :
'‎';
3071 $lrm =
"\xE2\x80\x8E"; # LEFT-TO-RIGHT MARK, commonly abbreviated LRM
3072 $rlm =
"\xE2\x80\x8F"; # RIGHT-TO-LEFT MARK, commonly abbreviated RLM
3074 return $this->
isRTL() ? $lrm : $rlm;
3076 return $this->
isRTL() ? $rlm : $lrm;
3083 return self::$dataCache->getItem( $this->mCode,
'capitalizeAllNouns' );
3094 switch ( $direction ) {
3096 return $this->
isRTL() ?
'←' :
'→';
3098 return $this->
isRTL() ?
'→' :
'←';
3116 return self::$dataCache->getItem( $this->mCode,
'linkPrefixExtension' );
3124 return self::$dataCache->getItem( $this->mCode,
'magicWords' );
3131 if ( $this->mMagicHookDone ) {
3134 $this->mMagicHookDone =
true;
3135 Hooks::run(
'LanguageGetMagic', [ &$this->mMagicExtensions, $this->
getCode() ] );
3145 if ( !$this->mMagicHookDone ) {
3149 if ( isset( $this->mMagicExtensions[$mw->mId] ) ) {
3150 $rawEntry = $this->mMagicExtensions[$mw->mId];
3152 $rawEntry = self::$dataCache->getSubitem(
3153 $this->mCode,
'magicWords', $mw->mId );
3156 if ( !is_array( $rawEntry ) ) {
3157 wfWarn(
"\"$rawEntry\" is not a valid magic word for \"$mw->mId\"" );
3159 $mw->mCaseSensitive = $rawEntry[0];
3160 $mw->mSynonyms = array_slice( $rawEntry, 1 );
3171 $fallbackChain = array_reverse( $fallbackChain );
3172 foreach ( $fallbackChain
as $code ) {
3173 if ( isset( $newWords[$code] ) ) {
3186 if ( is_null( $this->mExtendedSpecialPageAliases ) ) {
3188 $this->mExtendedSpecialPageAliases =
3189 self::$dataCache->getItem( $this->mCode,
'specialPageAliases' );
3191 [ &$this->mExtendedSpecialPageAliases, $this->
getCode() ] );
3204 return "<em>$text</em>";
3231 if ( !$nocommafy ) {
3232 $number = $this->
commafy( $number );
3235 $number = strtr( $number,
$s );
3239 if ( $wgTranslateNumerals ) {
3242 $number = strtr( $number,
$s );
3258 return $this->
formatNum( $number,
true );
3269 $s = array_filter(
$s );
3270 $number = strtr( $number, array_flip(
$s ) );
3276 $s = array_filter(
$s );
3277 $number = strtr( $number, array_flip(
$s ) );
3280 $number = strtr( $number, [
',' =>
'' ] );
3292 if ( $number === null ) {
3298 return strrev( (
string)preg_replace(
'/(\d{3})(?=\d)(?!\d*\.)/',
'$1,', strrev( $number ) ) );
3302 if ( intval( $number ) < 0 ) {
3305 $number = substr( $number, 1 );
3310 preg_match(
"/\d+/", $number, $integerPart );
3311 preg_match(
"/\.\d*/", $number, $decimalPart );
3312 $groupedNumber = ( count( $decimalPart ) > 0 ) ? $decimalPart[0] :
"";
3313 if ( $groupedNumber === $number ) {
3315 return $sign . $groupedNumber;
3317 $start = $end = ( $integerPart ) ? strlen( $integerPart[0] ) : 0;
3318 while ( $start > 0 ) {
3319 $match =
$matches[0][$numMatches - 1];
3320 $matchLen = strlen( $match );
3321 $start = $end - $matchLen;
3325 $groupedNumber = substr( $number, $start, $end -$start ) . $groupedNumber;
3327 if ( $numMatches > 1 ) {
3332 $groupedNumber =
"," . $groupedNumber;
3335 return $sign . $groupedNumber;
3343 return self::$dataCache->getItem( $this->mCode,
'digitGroupingPattern' );
3350 return self::$dataCache->getItem( $this->mCode,
'digitTransformTable' );
3357 return self::$dataCache->getItem( $this->mCode,
'separatorTransformTable' );
3370 $m = count( $l ) - 1;
3375 $and = $this->
msg(
'and' )->escaped();
3376 $space = $this->
msg(
'word-separator' )->escaped();
3378 $comma = $this->
msg(
'comma-separator' )->escaped();
3382 for ( $i = $m - 1; $i >= 0; $i-- ) {
3383 if ( $i == $m - 1 ) {
3384 $s = $l[$i] . $and . $space .
$s;
3386 $s = $l[$i] . $comma .
$s;
3400 wfMessage(
'comma-separator' )->inLanguage( $this )->escaped(),
3413 wfMessage(
'semicolon-separator' )->inLanguage( $this )->escaped(),
3425 wfMessage(
'pipe-separator' )->inLanguage( $this )->escaped(),
3447 function truncate( $string, $length, $ellipsis =
'...', $adjustLength =
true ) {
3448 # Use the localized ellipsis character
3449 if ( $ellipsis ==
'...' ) {
3450 $ellipsis =
wfMessage(
'ellipsis' )->inLanguage( $this )->escaped();
3452 # Check if there is no need to truncate
3453 if ( $length == 0 ) {
3455 } elseif ( strlen( $string ) <= abs( $length ) ) {
3458 $stringOriginal = $string;
3459 # If ellipsis length is >= $length then we can't apply $adjustLength
3460 if ( $adjustLength && strlen( $ellipsis ) >= abs( $length ) ) {
3461 $string = $ellipsis;
3462 # Otherwise, truncate and add ellipsis...
3464 $eLength = $adjustLength ? strlen( $ellipsis ) : 0;
3465 if ( $length > 0 ) {
3466 $length -= $eLength;
3467 $string = substr( $string, 0, $length );
3469 $string = rtrim( $string );
3470 $string = $string . $ellipsis;
3472 $length += $eLength;
3473 $string = substr( $string, $length );
3475 $string = ltrim( $string );
3476 $string = $ellipsis . $string;
3479 # Do not truncate if the ellipsis makes the string longer/equal (bug 22181).
3480 # This check is *not* redundant if $adjustLength, due to the single case where
3481 # LEN($ellipsis) > ABS($limit arg); $stringOriginal could be shorter than $string.
3482 if ( strlen( $string ) < strlen( $stringOriginal ) ) {
3485 return $stringOriginal;
3497 if ( $string !=
'' ) {
3498 $char = ord( $string[strlen( $string ) - 1] );
3500 if ( $char >= 0xc0 ) {
3501 # We got the first byte only of a multibyte char; remove it.
3502 $string = substr( $string, 0, -1 );
3503 } elseif ( $char >= 0x80 &&
3505 preg_match(
'/^(.*)(?:[\xe0-\xef][\x80-\xbf]|' .
3506 '[\xf0-\xf7][\x80-\xbf]{1,2})$/s', $string, $m )
3508 # We chopped in the middle of a character; remove it
3523 if ( $string !=
'' ) {
3524 $char = ord( $string[0] );
3525 if ( $char >= 0x80 && $char < 0xc0 ) {
3526 # We chopped in the middle of a character; remove the whole thing
3527 $string = preg_replace(
'/^[\x80-\xbf]+/',
'', $string );
3549 # Use the localized ellipsis character
3550 if ( $ellipsis ==
'...' ) {
3551 $ellipsis =
wfMessage(
'ellipsis' )->inLanguage( $this )->escaped();
3553 # Check if there is clearly no need to truncate
3554 if ( $length <= 0 ) {
3556 } elseif ( strlen( $text ) <= $length ) {
3561 $testingEllipsis =
false;
3569 $textLen = strlen( $text );
3570 $neLength = max( 0, $length - strlen( $ellipsis ) );
3571 for ( $pos = 0;
true; ++$pos ) {
3572 # Consider truncation once the display length has reached the maximim.
3573 # We check if $dispLen > 0 to grab tags for the $neLength = 0 case.
3574 # Check that we're not in the middle of a bracket/entity...
3575 if ( $dispLen && $dispLen >= $neLength && $bracketState == 0 && !$entityState ) {
3576 if ( !$testingEllipsis ) {
3577 $testingEllipsis =
true;
3578 # Save where we are; we will truncate here unless there turn out to
3579 # be so few remaining characters that truncation is not necessary.
3580 if ( !$maybeState ) {
3581 $maybeState = [
$ret, $openTags ];
3583 } elseif ( $dispLen > $length && $dispLen > strlen( $ellipsis ) ) {
3584 # String in fact does need truncation, the truncation point was OK.
3585 list(
$ret, $openTags ) = $maybeState;
3591 if ( $pos >= $textLen ) {
3595 # Read the next char...
3597 $lastCh = $pos ? $text[$pos - 1] :
'';
3603 } elseif ( $ch ==
'>' ) {
3607 } elseif ( $bracketState == 1 ) {
3615 } elseif ( $bracketState == 2 ) {
3622 } elseif ( $bracketState == 0 ) {
3623 if ( $entityState ) {
3629 if ( $neLength == 0 && !$maybeState ) {
3632 $maybeState = [ substr(
$ret, 0, -1 ), $openTags ];
3639 $max = ( $testingEllipsis ? $length : $neLength ) - $dispLen;
3641 $dispLen += $skipped;
3649 while ( count( $openTags ) > 0 ) {
3650 $ret .=
'</' . array_pop( $openTags ) .
'>';
3667 if ( $len === null ) {
3669 } elseif ( $len < 0 ) {
3673 if ( $start < strlen( $text ) ) {
3674 $skipCount = strcspn( $text, $search, $start, $len );
3675 $ret .= substr( $text, $start, $skipCount );
3692 if ( $tagType == 0 && $lastCh !=
'/' ) {
3694 } elseif ( $tagType == 1 ) {
3695 if ( $openTags &&
$tag == $openTags[count( $openTags ) - 1] ) {
3696 array_pop( $openTags );
3713 if ( isset( $wgGrammarForms[$this->
getCode()][$case][$word] ) ) {
3714 return $wgGrammarForms[$this->
getCode()][$case][$word];
3726 if ( isset( $wgGrammarForms[$this->
getCode()] )
3727 && is_array( $wgGrammarForms[$this->
getCode()] )
3729 return $wgGrammarForms[$this->
getCode()];
3754 if ( !count( $forms ) ) {
3758 if ( $gender ===
'male' ) {
3761 if ( $gender ===
'female' ) {
3764 return isset( $forms[2] ) ? $forms[2] : $forms[0];
3785 if ( is_string( $forms ) ) {
3788 if ( !count( $forms ) ) {
3793 $pluralForm = min( $pluralForm, count( $forms ) - 1 );
3794 return $forms[$pluralForm];
3813 foreach ( $forms
as $index => $form ) {
3814 if ( preg_match(
'/\d+=/i', $form ) ) {
3815 $pos = strpos( $form,
'=' );
3816 if ( substr( $form, 0, $pos ) === (
string)
$count ) {
3817 return substr( $form, $pos + 1 );
3819 unset( $forms[$index] );
3822 return array_values( $forms );
3834 while ( count( $forms ) <
$count ) {
3835 $forms[] = $forms[count( $forms ) - 1];
3858 if (
$dir ===
'ltr' ) {
3860 return self::$lre . $text . self::$pdf;
3862 if (
$dir ===
'rtl' ) {
3864 return self::$rle . $text . self::$pdf;
3884 foreach ( $duration
as $show =>
$value ) {
3885 if ( strcmp( $str,
$value ) == 0 ) {
3886 return htmlspecialchars( trim( $show ) );
3891 foreach ( $duration
as $show =>
$value ) {
3893 return htmlspecialchars( trim( $show ) );
3899 $time = strtotime( $str, 0 );
3900 if (
$time ===
false ) {
3902 } elseif (
$time !== strtotime( $str, 1 ) ) {
3906 if (
$time === 0 ) {
3908 $time =
'19700101000000';
3955 return $this->mConverter->autoConvertToAllVariants( $text );
3965 return $this->mConverter->convert( $text );
3975 return $this->mConverter->convertTitle(
$title );
3985 return $this->mConverter->convertNamespace( $ns );
4005 return (
bool)$this->mConverter->validateVariant( $variant );
4016 return htmlspecialchars( $this->
convert( $text, $isTitle ) );
4024 return $this->mConverter->convertCategoryKey( $key );
4034 return $this->mConverter->getVariants();
4041 return $this->mConverter->getPreferredVariant();
4048 return $this->mConverter->getDefaultVariant();
4055 return $this->mConverter->getURLVariant();
4071 $this->mConverter->findVariantLink(
$link, $nt, $ignoreOtherCond );
4081 return $this->mConverter->getExtraHashOptions();
4092 return $this->mConverter->getParsedTitle();
4102 $this->mConverter->updateConversionTable( $title );
4120 return $this->mConverter->markNoConversion( $text );
4133 return self::$dataCache->getItem( $this->mCode,
'linkTrail' );
4143 return self::$dataCache->getItem( $this->mCode,
'linkPrefixCharset' );
4154 if ( $this->mParentLanguage !==
false ) {
4160 $this->mParentLanguage = null;
4164 if ( !
$lang->hasVariant( $this->getCode() ) ) {
4165 $this->mParentLanguage = null;
4169 $this->mParentLanguage =
$lang;
4207 if ( is_null( $this->mHtmlCode ) ) {
4217 $this->mCode =
$code;
4219 $this->mHtmlCode = null;
4220 $this->mParentLanguage =
false;
4232 preg_match(
'/' . preg_quote( $prefix,
'/' ) .
'([A-Z][a-z_]+)' .
4233 preg_quote( $suffix,
'/' ) .
'/', $filename, $m );
4234 if ( !count( $m ) ) {
4237 return str_replace(
'_',
'-', strtolower( $m[1] ) );
4245 if (
$code ==
'en' ) {
4248 return 'Language' . str_replace(
'-',
'_',
ucfirst(
$code ) );
4261 if ( !self::isValidBuiltInCode(
$code ) ) {
4262 throw new MWException(
"Invalid language code \"$code\"" );
4265 return $prefix . str_replace(
'-',
'_',
ucfirst(
$code ) ) . $suffix;
4274 $file = self::getFileName(
"$IP/languages/messages/Messages",
$code,
'.php' );
4288 if ( !self::isValidBuiltInCode(
$code ) ) {
4289 throw new MWException(
"Invalid language code \"$code\"" );
4292 return "$IP/languages/i18n/$code.json";
4303 $fallbacks = self::getFallbacksFor(
$code );
4305 return $fallbacks[0];
4323 return self::getLocalisationCache()->getItem(
$code,
'fallbackSequence' ) ?: [
'en' ];
4339 $cacheKey =
"{$code}-{$wgLanguageCode}";
4341 if ( !array_key_exists( $cacheKey, self::$fallbackLanguageCache ) ) {
4342 $fallbacks = self::getFallbacksFor(
$code );
4345 $siteFallbacks = self::getFallbacksFor( $wgLanguageCode );
4346 array_unshift( $siteFallbacks, $wgLanguageCode );
4349 $siteFallbacks = array_diff( $siteFallbacks, $fallbacks );
4351 self::$fallbackLanguageCache[$cacheKey] = [ $fallbacks, $siteFallbacks ];
4353 return self::$fallbackLanguageCache[$cacheKey];
4366 return self::getLocalisationCache()->getItem(
$code,
'messages' );
4378 return self::getLocalisationCache()->getSubitem(
$code,
'messages', $key );
4390 return self::getLocalisationCache()->getSubitemList(
$code,
'messages' );
4398 if ( strpos( $talk,
'$1' ) ===
false ) {
4403 $talk = str_replace(
'$1', $wgMetaNamespace, $talk );
4405 # Allow grammar transformations
4406 # Allowing full message-style parsing would make simple requests
4407 # such as action=raw much more expensive than they need to be.
4408 # This will hopefully cover most cases.
4409 $talk = preg_replace_callback(
'/{{grammar:(.*?)\|(.*?)}}/i',
4410 [ &$this,
'replaceGrammarInNamespace' ], $talk );
4411 return str_replace(
' ',
'_', $talk );
4432 public function formatExpiry( $expiry, $format =
true, $infinity =
'infinity' ) {
4434 if ( $dbInfinity === null ) {
4438 if ( $expiry ==
'' || $expiry ===
'infinity' || $expiry == $dbInfinity ) {
4439 return $format ===
true
4443 return $format ===
true
4462 if ( !is_array( $format ) ) {
4463 $format = [
'avoid' => $format ];
4465 if ( !isset( $format[
'avoid'] ) ) {
4466 $format[
'avoid'] =
false;
4468 if ( !isset( $format[
'noabbrevs'] ) ) {
4469 $format[
'noabbrevs'] =
false;
4472 $format[
'noabbrevs'] ?
'seconds' :
'seconds-abbrev' )->inLanguage( $this );
4474 $format[
'noabbrevs'] ?
'minutes' :
'minutes-abbrev' )->inLanguage( $this );
4476 $format[
'noabbrevs'] ?
'hours' :
'hours-abbrev' )->inLanguage( $this );
4478 $format[
'noabbrevs'] ?
'days' :
'days-abbrev' )->inLanguage( $this );
4480 if ( round( $seconds * 10 ) < 100 ) {
4481 $s = $this->
formatNum( sprintf(
"%.1f", round( $seconds * 10 ) / 10 ) );
4482 $s = $secondsMsg->params(
$s )->text();
4483 } elseif ( round( $seconds ) < 60 ) {
4485 $s = $secondsMsg->params(
$s )->text();
4486 } elseif ( round( $seconds ) < 3600 ) {
4487 $minutes = floor( $seconds / 60 );
4488 $secondsPart = round( fmod( $seconds, 60 ) );
4489 if ( $secondsPart == 60 ) {
4493 $s = $minutesMsg->params( $this->
formatNum( $minutes ) )->text();
4495 $s .= $secondsMsg->params( $this->
formatNum( $secondsPart ) )->text();
4496 } elseif ( round( $seconds ) <= 2 * 86400 ) {
4497 $hours = floor( $seconds / 3600 );
4498 $minutes = floor( ( $seconds - $hours * 3600 ) / 60 );
4499 $secondsPart = round( $seconds - $hours * 3600 - $minutes * 60 );
4500 if ( $secondsPart == 60 ) {
4504 if ( $minutes == 60 ) {
4508 $s = $hoursMsg->params( $this->
formatNum( $hours ) )->text();
4510 $s .= $minutesMsg->params( $this->
formatNum( $minutes ) )->text();
4511 if ( !in_array( $format[
'avoid'], [
'avoidseconds',
'avoidminutes' ] ) ) {
4512 $s .=
' ' . $secondsMsg->params( $this->
formatNum( $secondsPart ) )->text();
4515 $days = floor( $seconds / 86400 );
4516 if ( $format[
'avoid'] ===
'avoidminutes' ) {
4517 $hours = round( ( $seconds - $days * 86400 ) / 3600 );
4518 if ( $hours == 24 ) {
4522 $s = $daysMsg->params( $this->
formatNum( $days ) )->text();
4524 $s .= $hoursMsg->params( $this->
formatNum( $hours ) )->text();
4525 } elseif ( $format[
'avoid'] ===
'avoidseconds' ) {
4526 $hours = floor( ( $seconds - $days * 86400 ) / 3600 );
4527 $minutes = round( ( $seconds - $days * 86400 - $hours * 3600 ) / 60 );
4528 if ( $minutes == 60 ) {
4532 if ( $hours == 24 ) {
4536 $s = $daysMsg->params( $this->
formatNum( $days ) )->text();
4538 $s .= $hoursMsg->params( $this->
formatNum( $hours ) )->text();
4540 $s .= $minutesMsg->params( $this->
formatNum( $minutes ) )->text();
4542 $s = $daysMsg->params( $this->
formatNum( $days ) )->text();
4573 return str_replace(
'$1', $this->
formatNum( $size ),
4577 $sizes = [
'',
'kilo',
'mega',
'giga',
'tera',
'peta',
'exa',
'zeta',
'yotta' ];
4580 $maxIndex = count( $sizes ) - 1;
4581 while ( $size >= $boundary && $index < $maxIndex ) {
4592 $msg = str_replace(
'$1', $sizes[$index], $messageKey );
4594 $size = round( $size, $round );
4596 return str_replace(
'$1', $this->
formatNum( $size ), $text );
4631 $this->
msg(
'word-separator' )->escaped() .
4632 $this->
msg(
'parentheses' )->rawParams( $details )->escaped();
4650 # Make 'previous' link
4651 $prev =
wfMessage(
'prevn' )->inLanguage( $this )->title( $title )->numParams(
$limit )->text();
4652 if ( $offset > 0 ) {
4654 $query, $prev,
'prevn-title',
'mw-prevlink' );
4656 $plink = htmlspecialchars( $prev );
4660 $next =
wfMessage(
'nextn' )->inLanguage( $this )->title( $title )->numParams(
$limit )->text();
4662 $nlink = htmlspecialchars( $next );
4665 $query, $next,
'nextn-title',
'mw-nextlink' );
4668 # Make links to set number of items per page
4670 foreach ( [ 20, 50, 100, 250, 500 ]
as $num ) {
4671 $numLinks[] = $this->
numLink( $title, $offset, $num,
4675 return wfMessage(
'viewprevnext' )->inLanguage( $this )->title( $title
4676 )->rawParams( $plink, $nlink, $this->
pipeList( $numLinks ) )->escaped();
4694 $query = [
'limit' =>
$limit,
'offset' => $offset ] +
$query;
4695 $tooltip =
wfMessage( $tooltipMsg )->inLanguage( $this )->title( $title )
4696 ->numParams(
$limit )->text();
4699 'title' => $tooltip,
'class' => $class ],
$link );
4708 return $this->mConverter->getConvRuleTitle();
4717 $pluralRules = self::$dataCache->getItem( strtolower( $this->mCode ),
'compiledPluralRules' );
4719 if ( !$pluralRules ) {
4720 foreach ( $fallbacks
as $fallbackCode ) {
4721 $pluralRules = self::$dataCache->getItem( strtolower( $fallbackCode ),
'compiledPluralRules' );
4722 if ( $pluralRules ) {
4727 return $pluralRules;
4736 $pluralRules = self::$dataCache->getItem( strtolower( $this->mCode ),
'pluralRules' );
4738 if ( !$pluralRules ) {
4739 foreach ( $fallbacks
as $fallbackCode ) {
4740 $pluralRules = self::$dataCache->getItem( strtolower( $fallbackCode ),
'pluralRules' );
4741 if ( $pluralRules ) {
4746 return $pluralRules;
4755 $pluralRuleTypes = self::$dataCache->getItem( strtolower( $this->mCode ),
'pluralRuleTypes' );
4757 if ( !$pluralRuleTypes ) {
4758 foreach ( $fallbacks
as $fallbackCode ) {
4759 $pluralRuleTypes = self::$dataCache->getItem( strtolower( $fallbackCode ),
'pluralRuleTypes' );
4760 if ( $pluralRuleTypes ) {
4765 return $pluralRuleTypes;
4775 $form = Evaluator::evaluateCompiled( $number, $pluralRules );
4790 if ( isset( $pluralRuleTypes[$index] ) ) {
4791 return $pluralRuleTypes[$index];
utf8ToCodepoint($char)
Determine the Unicode codepoint of a single-character UTF-8 sequence.
#define the
table suitable for use with IDatabase::select()
formatTimePeriod($seconds, $format=[])
getDirMark($opposite=false)
A hidden direction mark (LRM or RLM), depending on the language direction.
getSpecialPageAliases()
Get special page names, as an associative array canonical name => array of valid names, including aliases.
getWeekdayAbbreviation($key)
getDateFormatString($type, $pref)
Get a format string for a given type and preference.
getPluralRuleTypes()
Get the plural rule types for the language.
getHumanTimestamp(MWTimestamp $time, MWTimestamp $relativeTo=null, User $user=null)
Get the timestamp in a human-friendly relative format, e.g., "3 days ago".
static getLocalisationCache()
Get the LocalisationCache instance.
convertPlural($count, $forms)
Plural form transformations, needed for some languages.
diff(MWTimestamp $relativeTo)
Calculate the difference between two MWTimestamp objects.
Wrapper around strtr() that holds replacements.
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
doMagicHook()
Run the LanguageGetMagic hook once.
wfGetDB($db, $groups=[], $wiki=false)
Get a Database object.
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output $out
static isKnownLanguageTag($tag)
Returns true if a language code is an IETF tag known to MediaWiki.
the array() calling protocol came about after MediaWiki 1.4rc1.
static insertSpace($string, $pattern)
null for the local wiki Added should default to null in handler for backwards compatibility add a value to it if you want to add a cookie that have to vary cache options can modify $query
convertGrammar($word, $case)
Grammatical transformations, needed for inflected languages Invoked by putting {{grammar:case|word}} ...
static LocalisationCache $dataCache
handleExplicitPluralForms($count, array $forms)
Handles explicit plural forms for Language::convertPlural()
hasVariant($variant)
Check if the language has the specific variant.
markNoConversion($text, $noParse=false)
Prepare external link text for conversion.
setNamespaces(array $namespaces)
Arbitrarily set all of the namespace names at once.
format($format)
Format the timestamp in a given format.
static HashBagOStuff null $languageNameCache
Cache for language names.
transformUsingPairFile($file, $string)
Transform a string using serialized data stored in the given file (which must be in the serialized su...
date($ts, $adj=false, $format=true, $timecorrection=false)
getHtmlCode()
Get the code in BCP 47 format which we can use inside of html lang="" tags.
truncate_skip(&$ret, $text, $search, $start, $len=null)
truncateHtml() helper function like strcspn() but adds the skipped chars to $ret
static isWellFormedLanguageTag($code, $lenient=false)
Returns true if a language code string is a well-formed language tag according to RFC 5646...
equals(Language $lang)
Compare with an other language object.
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
removeBadCharFirst($string)
Remove bytes that represent an incomplete Unicode character at the start of string (e...
convertNamespace($ns)
Convert a namespace index to a string in the preferred variant.
static getMessageFor($key, $code)
Get a message for a given language.
offsetForUser(User $user)
Adjust the timestamp depending on the given user's preferences.
getLocalNsIndex($text)
Get a namespace key by value, case insensitive.
alignEnd()
Return 'right' or 'left' as appropriate alignment for line-end for this language's text direction...
firstChar($s)
Get the first character of a string.
globals txt Globals are evil The original MediaWiki code relied on globals for processing context far too often MediaWiki development since then has been a story of slowly moving context out of global variables and into objects Storing processing context in object member variables allows those objects to be reused in a much more flexible way Consider the elegance of
database rows
$wgLangObjCacheSize
Language cache size, or really how many languages can we handle simultaneously without degrading to c...
if(!isset($args[0])) $lang
hasVariants()
Check if this is a language with variants.
getCompiledPluralRules()
Get the compiled plural rules for the language.
getNsIndex($text)
Get a namespace key by value, case insensitive.
getNsText($index)
Get a namespace value by key.
This code would result in ircNotify being run twice when an article is and once for brion Hooks can return three possible true was required This is the default since MediaWiki *some string
iconv($in, $out, $string)
$wgMetaNamespace
Name of the project namespace.
formatComputingNumbers($size, $boundary, $messageKey)
static getFallbacksIncludingSiteLanguage($code)
Get the ordered list of fallback languages, ending with the fallback language chain for the site lang...
static array $durationIntervals
formatNumNoSeparators($number)
Front-end for non-commafied formatNum.
truncate_endBracket(&$tag, $tagType, $lastCh, &$openTags)
truncateHtml() helper function (a) push or pop $tag from $openTags as needed (b) clear $tag value ...
A fake language converter.
linkTrail()
A regular expression to match legal word-trailing characters which should be merged onto a link of th...
wfUrlProtocolsWithoutProtRel()
Like wfUrlProtocols(), but excludes '//' from the protocol list.
normalize($s)
Convert a UTF-8 string to normal form C.
$wgNamespaceAliases
Namespace aliases.
static getCodeFromFileName($filename, $prefix= 'Language', $suffix= '.php')
Get the language code from a file name.
internalUserTimeAndDate($type, $ts, User $user, array $options)
Internal helper function for userDate(), userTime() and userTimeAndDate()
static getMessageKeysFor($code)
Get all message keys for a given language.
static tsToHijri($ts)
Converting Gregorian dates to Hijri dates.
formatExpiry($expiry, $format=true, $infinity= 'infinity')
Decode an expiry (block, protection, etc) which has come from the DB.
getVariants()
Get the list of variants supported by this language see sample implementation in LanguageZh.php.
Represents a title within MediaWiki.
dateFormat($usePrefs=true)
This is meant to be used by time(), date(), and timeanddate() to get the date preference they're supp...
when a variable name is used in a it is silently declared as a new local masking the global
autoConvertToAllVariants($text)
convert text to all supported variants
static getFallbacksFor($code)
Get the ordered list of fallback languages.
We ve cleaned up the code here by removing clumps of infrequently used code and moving them off somewhere else It s much easier for someone working with this code to see what s _really_ going and make changes or fix bugs In we can take all the code that deals with the little used title reversing options(say) and put it in one place.Instead of having little title-reversing if-blocks spread all over the codebase in showAnArticle
$wgExtraGenderNamespaces
Same as above, but for namespaces with gender distinction.
parseFormattedNumber($number)
$wgTranslateNumerals
For Hindi and Arabic use local numerals instead of Western style (0-9) numerals in interface...
see documentation in includes Linker php for Linker::makeImageLink & $time
static $mWeekdayAbbrevMsgs
the value to return A Title object or null for latest to be modified or replaced by the hook handler or if authentication is not possible after cache objects are set for highlighting & $link
static newFromCode($code)
Create a language object for a given language code.
The User object encapsulates all of the user-specific settings (user_id, name, rights, email address, options, last login time).
time($ts, $adj=false, $format=true, $timecorrection=false)
embedBidi($text= '')
Wraps argument with unicode control characters for directionality safety.
static getJsonMessagesFileName($code)
wfTimestamp($outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
$wgLanguageCode
Site language code.
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 true
formatSize($size)
Format a size in bytes for output, using an appropriate unit (B, KB, MB, GB, TB, PB, EB, ZB or YB) according to the magnitude in question.
semicolonList(array $list)
Take a list of strings and build a locale-friendly semicolon-separated list, using the local semicolo...
addMagicWordsByLang($newWords)
Add magic words to the extension array.
segmentForDiff($text)
languages like Chinese need to be segmented in order for the diff to be of any use ...
static $lre
Unicode directional formatting characters, for embedBidi()
convertHtml($text, $isTitle=false)
Perform output conversion on a string, and encode for safe HTML output.
when a variable name is used in a function
ucwordbreaksCallbackAscii($matches)
static $mHijriCalendarMonthMsgs
ucwordsCallbackMB($matches)
linkPrefixCharset()
A regular expression character set to match legal word-prefixing characters which should be merged on...
static getMain()
Static methods.
getIranianCalendarMonthName($key)
LanguageConverter $mConverter
msg($msg)
Get message object in this language.
__destruct()
Reduce memory usage.
formatBitrate($bps)
Format a bitrate for output, using an appropriate unit (bps, kbps, Mbps, Gbps, Tbps, Pbps, Ebps, Zbps or Ybps) according to the magnitude in question.
truncateHtml($text, $length, $ellipsis= '...')
Truncate a string of valid HTML to a specified length in bytes, appending an optional string (e...
$wgLocalisationCacheConf
Localisation cache configuration.
getArrow($direction= 'forwards')
An arrow, depending on the language direction.
static array static array $fallbackLanguageCache
Cache for language fallbacks.
wfWarn($msg, $callerOffset=1, $level=E_USER_NOTICE)
Send a warning either to the debug log or in a PHP error depending on $wgDevelopmentWarnings.
static convertDoubleWidth($string)
convert double-width roman characters to single-width.
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context $options
viewPrevNext(Title $title, $offset, $limit, array $query=[], $atend=false)
Generate (prev x| next x) (20|50|100...) type links for paging.
getConverter()
Return the LanguageConverter used in the Language.
static $mIranianCalendarMonthMsgs
static hebrewNumeral($num)
Hebrew Gematria number formatting up to 9999.
getFormattedNsText($index)
A convenience function that returns the same thing as getNsText() except with '_' changed to ' '...
getMonthAbbreviation($key)
getLocalURL($query= '', $query2=false)
Get a URL with no fragment or server name (relative URL) from a Title object.
static tsToHebrew($ts)
Converting Gregorian dates to Hebrew dates.
getBookstoreList()
Exports $wgBookstoreListEn.
listToText(array $l)
Take a list of strings and build a locale-friendly comma-separated list, using the local comma-separa...
$wgDummyLanguageCodes
List of language codes that don't correspond to an actual language.
caseFold($s)
Return a case-folded representation of $s.
static getMessagesFileName($code)
Internationalisation code.
$wgAllUnicodeFixes
Set this to always convert certain Unicode sequences to modern ones regardless of the content languag...
static isValidBuiltInCode($code)
Returns true if a language code is of a valid form for the purposes of internal customisation of Medi...
getTimestamp($style=TS_UNIX)
Get the timestamp represented by this object in a certain form.
static isValidCode($code)
Returns true if a language code string is of a valid form, whether or not it exists.
uc($str, $first=false)
Convert a string to uppercase.
static getMessagesFor($code)
Get all messages for a given language WARNING: this may take a long time.
ucwordbreaksCallbackMB($matches)
static $strongDirRegex
Directionality test regex for embedBidi().
needsGenderDistinction()
Whether this language uses gender-dependent namespace aliases.
wfIsInfinity($str)
Determine input string is represents as infinity.
getHebrewCalendarMonthNameGen($key)
updateConversionTable(Title $title)
Refresh the cache of conversion tables when MediaWiki:Conversiontable* is updated.
convertTitle($title)
Convert a Title object to a string in the preferred variant.
convert($text)
convert text to different variants of a language.
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 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 after processing after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation 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 unsetoffset-wrap String Wrap the message in html(usually something like"<
wfBCP47($code)
Get the normalised IETF language tag See unit test for examples.
$wgMetaNamespaceTalk
Name of the project talk namespace.
Allows to change the fields on the form that will be generated are created Can be used to omit specific feeds from being outputted You must not use this hook to add use OutputPage::addFeedLink() instead.&$feedLinks conditions will AND in the final query as a Content object as a Content object $title
getVariantname($code, $usemsg=true)
short names for language variants used for language conversion links.
static getFileName($prefix= 'Language', $code, $suffix= '.php')
Get the name of a file for a certain language code.
formatDuration($seconds, array $chosenIntervals=[])
Takes a number of seconds and turns it into a text using values such as hours and minutes...
static run($event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
static getSuggestedDurations($lang=null)
Get an array of suggested block durations from MediaWiki:Ipboptions.
ucwordbreaks($str)
capitalize words at word breaks
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books $tag
userTime($ts, User $user, array $options=[])
Get the formatted time for the given timestamp and formatted for the given user.
static $mHebrewCalendarMonthMsgs
pipeList(array $list)
Same as commaList, but separate it with the pipe instead.
getMessageFromDB($msg)
Get a message from the MediaWiki namespace.
formatNum($number, $nocommafy=false)
Normally we output all numbers in plain en_US style, that is 293,291.235 for twohundredninetythreetho...
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 & $ret
$mExtendedSpecialPageAliases
namespace and then decline to actually register it & $namespaces
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
getPluralRules()
Get the plural rules for the language.
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output modifiable & $code
static fetchLanguageName($code, $inLanguage=null, $include= 'all')
resetNamespaces()
Resets all of the namespace caches.
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a local account $user
segmentByWord($string)
Some languages such as Chinese require word segmentation, Specify such segmentation when overridden i...
getMagicWords()
Get all magic words from cache.
numLink(Title $title, $offset, $limit, array $query, $link, $tooltipMsg, $class)
Helper function for viewPrevNext() that generates links.
ucfirst($str)
Make a string's first character uppercase.
getOption($oname, $defaultOverride=null, $ignoreHidden=false)
Get the user's current setting for a given option.
getHijriCalendarMonthName($key)
static getFallbackFor($code)
Get the first fallback for a given language.
timeanddate($ts, $adj=false, $format=true, $timecorrection=false)
getPluralRuleType($number)
Find the plural rule type appropriate for the given number For example, if the language is set to Ara...
userAdjust($ts, $tz=false)
Used by date() and time() to adjust the time output.
userDate($ts, User $user, array $options=[])
Get the formatted date for the given timestamp and formatted for the given user.
getConvRuleTitle()
Get the conversion rule title, if any.
const TS_MW
MediaWiki concatenated string timestamp (YYYYMMDDHHMMSS)
getMagic($mw)
Fill a MagicWord object with data from here.
static classFromCode($code)
$wgExtraNamespaces
Additional namespaces.
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
getHumanTimestampInternal(MWTimestamp $ts, MWTimestamp $relativeTo, User $user)
Convert an MWTimestamp into a pretty human-readable timestamp using the given user preferences and re...
getCode()
Get the internal language code for this language object.
replaceGrammarInNamespace($m)
commafy($number)
Adds commas to a given number.
sprintfDate($format, $ts, DateTimeZone $zone=null, &$ttl= 'unused')
This is a workalike of PHP's date() function, but with better internationalisation, a reduced set of format characters, and a better escaping format.
userTimeAndDate($ts, User $user, array $options=[])
Get the formatted date and time for the given timestamp and formatted for the given user...
translateBlockExpiry($str, User $user=null)
truncate($string, $length, $ellipsis= '...', $adjustLength=true)
Truncate a string to a specified length in bytes, appending an optional string (e.g.
static romanNumeral($num)
Roman number formatting up to 10000.
convertForSearchResult($termsArray)
removeBadCharLast($string)
Remove bytes that represent an incomplete Unicode character at the end of string (e.g.
return['DBLoadBalancerFactory'=> function(MediaWikiServices $services){$config=$services->getMainConfig() ->get( 'LBFactoryConf');$class=LBFactory::getLBFactoryClass($config);if(!isset($config['readOnlyReason'])){$config['readOnlyReason']=wfConfiguredReadOnlyReason();}return new $class($config);},'DBLoadBalancer'=> function(MediaWikiServices $services){return $services->getDBLoadBalancerFactory() ->getMainLB();},'SiteStore'=> function(MediaWikiServices $services){$rawSiteStore=new DBSiteStore($services->getDBLoadBalancer());$cache=wfGetCache(wfIsHHVM()?CACHE_ACCEL:CACHE_ANYTHING);return new CachingSiteStore($rawSiteStore, $cache);},'SiteLookup'=> function(MediaWikiServices $services){return $services->getSiteStore();},'ConfigFactory'=> function(MediaWikiServices $services){$registry=$services->getBootstrapConfig() ->get( 'ConfigRegistry');$factory=new ConfigFactory();foreach($registry as $name=> $callback){$factory->register($name, $callback);}return $factory;},'MainConfig'=> function(MediaWikiServices $services){return $services->getConfigFactory() ->makeConfig( 'main');},'InterwikiLookup'=> function(MediaWikiServices $services){global $wgContLang;$config=$services->getMainConfig();return new ClassicInterwikiLookup($wgContLang, ObjectCache::getMainWANInstance(), $config->get( 'InterwikiExpiry'), $config->get( 'InterwikiCache'), $config->get( 'InterwikiScopes'), $config->get( 'InterwikiFallbackSite'));},'StatsdDataFactory'=> function(MediaWikiServices $services){return new BufferingStatsdDataFactory(rtrim($services->getMainConfig() ->get( 'StatsdMetricPrefix'), '.'));},'EventRelayerGroup'=> function(MediaWikiServices $services){return new EventRelayerGroup($services->getMainConfig() ->get( 'EventRelayerConfig'));},'SearchEngineFactory'=> function(MediaWikiServices $services){return new SearchEngineFactory($services->getSearchEngineConfig());},'SearchEngineConfig'=> function(MediaWikiServices $services){global $wgContLang;return new SearchEngineConfig($services->getMainConfig(), $wgContLang);},'SkinFactory'=> function(MediaWikiServices $services){$factory=new SkinFactory();$names=$services->getMainConfig() ->get( 'ValidSkinNames');foreach($names as $name=> $skin){$factory->register($name, $skin, function() use($name, $skin){$class="Skin$skin";return new $class($name);});}$factory->register( 'fallback', 'Fallback', function(){return new SkinFallback;});$factory->register( 'apioutput', 'ApiOutput', function(){return new SkinApi;});return $factory;},'WatchedItemStore'=> function(MediaWikiServices $services){$store=new WatchedItemStore($services->getDBLoadBalancer(), new HashBagOStuff([ 'maxKeys'=> 100]));$store->setStatsdDataFactory($services->getStatsdDataFactory());return $store;},'WatchedItemQueryService'=> function(MediaWikiServices $services){return new WatchedItemQueryService($services->getDBLoadBalancer());},'LinkCache'=> function(MediaWikiServices $services){return new LinkCache($services->getTitleFormatter());},'LinkRendererFactory'=> function(MediaWikiServices $services){return new LinkRendererFactory($services->getTitleFormatter(), $services->getLinkCache());},'LinkRenderer'=> function(MediaWikiServices $services){global $wgUser;if(defined( 'MW_NO_SESSION')){return $services->getLinkRendererFactory() ->create();}else{return $services->getLinkRendererFactory() ->createForUser($wgUser);}},'GenderCache'=> function(MediaWikiServices $services){return new GenderCache();},'_MediaWikiTitleCodec'=> function(MediaWikiServices $services){global $wgContLang;return new MediaWikiTitleCodec($wgContLang, $services->getGenderCache(), $services->getMainConfig() ->get( 'LocalInterwikis'));},'TitleFormatter'=> function(MediaWikiServices $services){return $services->getService( '_MediaWikiTitleCodec');},'TitleParser'=> function(MediaWikiServices $services){return $services->getService( '_MediaWikiTitleCodec');},]
static tsToIranian($ts)
Algorithm by Roozbeh Pournader and Mohammad Toossi to convert Gregorian dates to Iranian dates...
$transformData
ReplacementArray object caches.
specialList($page, $details, $oppositedm=true)
Make a list item, used by various special pages.
getExtraHashOptions()
returns language specific options used by User::getPageRenderHash() for example, the preferred langua...
getParsedTitle()
For languages that support multiple variants, the title of an article may be displayed differently in...
preConvertPlural($forms, $count)
Checks that convertPlural was given an array and pads it to requested amount of forms by copying the ...
findVariantLink(&$link, &$nt, $ignoreOtherCond=false)
If a language supports multiple variants, it is possible that non-existing link in one variant actual...
$wgGrammarForms
Some languages need different word forms, usually for different cases.
emphasize($text)
Italic is unsuitable for some languages.
getDirMarkEntity($opposite=false)
A hidden direction mark (LRM or RLM), depending on the language direction.
separatorTransformTable()
isRTL()
For right-to-left language support.
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context the output can only depend on parameters provided to this hook not on global state indicating whether full HTML should be generated If generation of HTML may be but other information should still be present in the ParserOutput object to manipulate or replace but no entry for that model exists in $wgContentHandlers if desired whether it is OK to use $contentModel on $title Handler functions that modify $ok should generally return false to prevent further hooks from further modifying $ok inclusive $limit
getDatePreference()
Get the user's preferred date format.
getParentLanguage()
Get the "parent" language which has a converter to convert a "compatible" language (in another varian...
getDir()
Return the correct HTML 'dir' attribute value for this language.
getFormattedNamespaces()
A convenience function that returns getNamespaces() with spaces instead of underscores in values...
$wgLocalTZoffset
Set an offset from UTC in minutes to use for the default timezone setting for anonymous users and new...
normalizeForSearch($string)
Some languages have special punctuation need to be normalized.
getDurationIntervals($seconds, array $chosenIntervals=[])
Takes a number of seconds and returns an array with a set of corresponding intervals.
linkPrefixExtension()
To allow "foo[[bar]]" to extend the link over the whole word "foobar".
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring which defines all default service and specifies how they depend on each other("wiring").When a new service is added to MediaWiki core
getGrammarForms()
Get the grammar forms for the content language.
static dateTimeObjFormat(&$dateTimeObj, $ts, $zone, $code)
Pass through result from $dateTimeObj->format()
=Architecture==Two class hierarchies are used to provide the functionality associated with the different content models:*Content interface(and AbstractContent base class) define functionality that acts on the concrete content of a page, and *ContentHandler base class provides functionality specific to a content model, but not acting on concrete content.The most important function of ContentHandler is to act as a factory for the appropriate implementation of Content.These Content objects are to be used by MediaWiki everywhere, instead of passing page content around as text.All manipulation and analysis of page content must be done via the appropriate methods of the Content object.For each content model, a subclass of ContentHandler has to be registered with $wgContentHandlers.The ContentHandler object for a given content model can be obtained using ContentHandler::getForModelID($id).Also Title, WikiPage and Revision now have getContentHandler() methods for convenience.ContentHandler objects are singletons that provide functionality specific to the content type, but not directly acting on the content of some page.ContentHandler::makeEmptyContent() and ContentHandler::unserializeContent() can be used to create a Content object of the appropriate type.However, it is recommended to instead use WikiPage::getContent() resp.Revision::getContent() to get a page's content as a Content object.These two methods should be the ONLY way in which page content is accessed.Another important function of ContentHandler objects is to define custom action handlers for a content model, see ContentHandler::getActionOverrides().This is similar to what WikiPage::getActionOverrides() was already doing.==Serialization==With the ContentHandler facility, page content no longer has to be text based.Objects implementing the Content interface are used to represent and handle the content internally.For storage and data exchange, each content model supports at least one serialization format via ContentHandler::serializeContent($content).The list of supported formats for a given content model can be accessed using ContentHandler::getSupportedFormats().Content serialization formats are identified using MIME type like strings.The following formats are built in:*text/x-wiki-wikitext *text/javascript-for js pages *text/css-for css pages *text/plain-for future use, e.g.with plain text messages.*text/html-for future use, e.g.with plain html messages.*application/vnd.php.serialized-for future use with the api and for extensions *application/json-for future use with the api, and for use by extensions *application/xml-for future use with the api, and for use by extensions In PHP, use the corresponding CONTENT_FORMAT_XXX constant.Note that when using the API to access page content, especially action=edit, action=parse and action=query &prop=revisions, the model and format of the content should always be handled explicitly.Without that information, interpretation of the provided content is not reliable.The same applies to XML dumps generated via maintenance/dumpBackup.php or Special:Export.Also note that the API will provide encapsulated, serialized content-so if the API was called with format=json, and contentformat is also json(or rather, application/json), the page content is represented as a string containing an escaped json structure.Extensions that use JSON to serialize some types of page content may provide specialized API modules that allow access to that content in a more natural form.==Compatibility==The ContentHandler facility is introduced in a way that should allow all existing code to keep functioning at least for pages that contain wikitext or other text based content.However, a number of functions and hooks have been deprecated in favor of new versions that are aware of the page's content model, and will now generate warnings when used.Most importantly, the following functions have been deprecated:*Revisions::getText() is deprecated in favor Revisions::getContent()*WikiPage::getText() is deprecated in favor WikiPage::getContent() Also, the old Article::getContent()(which returns text) is superceded by Article::getContentObject().However, both methods should be avoided since they do not provide clean access to the page's actual content.For instance, they may return a system message for non-existing pages.Use WikiPage::getContent() instead.Code that relies on a textual representation of the page content should eventually be rewritten.However, ContentHandler::getContentText() provides a stop-gap that can be used to get text for a page.Its behavior is controlled by $wgContentHandlerTextFallback it
getGenderNsText($index, $gender)
Returns gender-dependent namespace alias if available.
static getDefaultOption($opt)
Get a given default option value.
initContLang()
Hook which will be called if this is the content language.
static factory($code)
Get a cached or new language object for a given language code.
fixVariableInNamespace($talk)
getNamespaces()
Returns an array of localised namespaces indexed by their numbers.
wfGetPrecompiledData($name)
Get an object from the precompiled serialized directory.
gender($gender, $forms)
Provides an alternative text depending on specified gender.
commaList(array $list)
Take a list of strings and build a locale-friendly comma-separated list, using the local comma-separa...
static $mHebrewCalendarMonthGenMsgs
static array $languagesWithVariants
languages supporting variants
static element($element, $attribs=[], $contents= '')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
static getCanonicalIndex($name)
Returns the index for a given canonical name, or NULL The input must be converted to lower case first...
static getCanonicalNamespaces($rebuild=false)
Returns array of all defined namespaces with their canonical (English) names.
getMonthAbbreviationsArray()
Library for creating and parsing MW-style timestamps.
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached one of or reset my talk my contributions etc etc otherwise the built in rate limiting checks are if enabled allows for interception of redirect as a string mapping parameter names to values & $type
hasWordBreaks()
Most writing systems use whitespace to break up words.
static strongDirFromContent($text= '')
Gets directionality of the first strongly directional codepoint, for embedBidi()
static isSupportedLanguage($code)
Checks whether any localisation is available for that language tag in MediaWiki (MessagesXx.php exists).
alignStart()
Return 'left' or 'right' as appropriate alignment for line-start for this language's text direction...
static tsToYear($ts, $cName)
Algorithm to convert Gregorian dates to Thai solar dates, Minguo dates or Minguo dates.
getPluralRuleIndexNumber($number)
Find the index number of the plural rule appropriate for the given number.
static hebrewYearStart($year)
This calculates the Hebrew year start, as days since 1 September.
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached $page
getHebrewCalendarMonthName($key)
unsegmentForDiff($text)
and unsegment to show the result
Allows to change the fields on the form that will be generated $name