Index: trunk/phase3/maintenance/parserTests.inc |
— | — | @@ -76,6 +76,7 @@ |
77 | 77 | break; |
78 | 78 | } |
79 | 79 | } |
| 80 | + |
80 | 81 | $this->term = $this->color |
81 | 82 | ? new AnsiTermColorer() |
82 | 83 | : new DummyTermColorer(); |
— | — | @@ -163,6 +164,7 @@ |
164 | 165 | mt_srand( ++$this->fuzzSeed ); |
165 | 166 | $totalLength = mt_rand( 1, $this->maxFuzzTestLength ); |
166 | 167 | $input = ''; |
| 168 | + |
167 | 169 | while ( strlen( $input ) < $totalLength ) { |
168 | 170 | $logHairLength = mt_rand( 0, 1000000 ) / 1000000 * $logMaxLength; |
169 | 171 | $hairLength = min( intval( exp( $logHairLength ) ), $dictSize ); |
— | — | @@ -172,6 +174,7 @@ |
173 | 175 | |
174 | 176 | $this->setupGlobals(); |
175 | 177 | $parser = $this->getParser(); |
| 178 | + |
176 | 179 | // Run the test |
177 | 180 | try { |
178 | 181 | $parser->parse( $input, $title, $opts ); |
— | — | @@ -189,6 +192,7 @@ |
190 | 193 | } else { |
191 | 194 | $numSuccess++; |
192 | 195 | } |
| 196 | + |
193 | 197 | $numTotal++; |
194 | 198 | $this->teardownGlobals(); |
195 | 199 | $parser->__destruct(); |
— | — | @@ -199,6 +203,7 @@ |
200 | 204 | if ( $usage > 90 ) { |
201 | 205 | echo "Out of memory:\n"; |
202 | 206 | $memStats = $this->getMemoryBreakdown(); |
| 207 | + |
203 | 208 | foreach ( $memStats as $name => $usage ) { |
204 | 209 | echo "$name: $usage\n"; |
205 | 210 | } |
— | — | @@ -213,13 +218,16 @@ |
214 | 219 | */ |
215 | 220 | function getFuzzInput( $filenames ) { |
216 | 221 | $dict = ''; |
| 222 | + |
217 | 223 | foreach ( $filenames as $filename ) { |
218 | 224 | $contents = file_get_contents( $filename ); |
219 | 225 | preg_match_all( '/!!\s*input\n(.*?)\n!!\s*result/s', $contents, $matches ); |
| 226 | + |
220 | 227 | foreach ( $matches[1] as $match ) { |
221 | 228 | $dict .= $match . "\n"; |
222 | 229 | } |
223 | 230 | } |
| 231 | + |
224 | 232 | return $dict; |
225 | 233 | } |
226 | 234 | |
— | — | @@ -228,25 +236,33 @@ |
229 | 237 | */ |
230 | 238 | function getMemoryBreakdown() { |
231 | 239 | $memStats = array(); |
| 240 | + |
232 | 241 | foreach ( $GLOBALS as $name => $value ) { |
233 | 242 | $memStats['$' . $name] = strlen( serialize( $value ) ); |
234 | 243 | } |
| 244 | + |
235 | 245 | $classes = get_declared_classes(); |
| 246 | + |
236 | 247 | foreach ( $classes as $class ) { |
237 | 248 | $rc = new ReflectionClass( $class ); |
238 | 249 | $props = $rc->getStaticProperties(); |
239 | 250 | $memStats[$class] = strlen( serialize( $props ) ); |
240 | 251 | $methods = $rc->getMethods(); |
| 252 | + |
241 | 253 | foreach ( $methods as $method ) { |
242 | 254 | $memStats[$class] += strlen( serialize( $method->getStaticVariables() ) ); |
243 | 255 | } |
244 | 256 | } |
| 257 | + |
245 | 258 | $functions = get_defined_functions(); |
| 259 | + |
246 | 260 | foreach ( $functions['user'] as $function ) { |
247 | 261 | $rf = new ReflectionFunction( $function ); |
248 | 262 | $memStats["$function()"] = strlen( serialize( $rf->getStaticVariables() ) ); |
249 | 263 | } |
| 264 | + |
250 | 265 | asort( $memStats ); |
| 266 | + |
251 | 267 | return $memStats; |
252 | 268 | } |
253 | 269 | |
— | — | @@ -270,27 +286,33 @@ |
271 | 287 | $this->recorder->start(); |
272 | 288 | $this->setupDatabase(); |
273 | 289 | $ok = true; |
| 290 | + |
274 | 291 | foreach ( $filenames as $filename ) { |
275 | 292 | $tests = new TestFileIterator( $filename, $this ); |
276 | 293 | $ok = $this->runTests( $tests ) && $ok; |
277 | 294 | } |
| 295 | + |
278 | 296 | $this->teardownDatabase(); |
279 | 297 | $this->recorder->report(); |
280 | 298 | $this->recorder->end(); |
| 299 | + |
281 | 300 | return $ok; |
282 | 301 | } |
283 | 302 | |
284 | 303 | function runTests( $tests ) { |
285 | 304 | $ok = true; |
| 305 | + |
286 | 306 | foreach ( $tests as $i => $t ) { |
287 | 307 | $result = |
288 | 308 | $this->runTest( $t['test'], $t['input'], $t['result'], $t['options'], $t['config'] ); |
289 | 309 | $ok = $ok && $result; |
290 | 310 | $this->recorder->record( $t['test'], $result ); |
291 | 311 | } |
| 312 | + |
292 | 313 | if ( $this->showProgress ) { |
293 | 314 | print "\n"; |
294 | 315 | } |
| 316 | + |
295 | 317 | return $ok; |
296 | 318 | } |
297 | 319 | |
— | — | @@ -299,16 +321,21 @@ |
300 | 322 | */ |
301 | 323 | function getParser( $preprocessor = null ) { |
302 | 324 | global $wgParserConf; |
| 325 | + |
303 | 326 | $class = $wgParserConf['class']; |
304 | 327 | $parser = new $class( array( 'preprocessorClass' => $preprocessor ) + $wgParserConf ); |
| 328 | + |
305 | 329 | foreach ( $this->hooks as $tag => $callback ) { |
306 | 330 | $parser->setHook( $tag, $callback ); |
307 | 331 | } |
| 332 | + |
308 | 333 | foreach ( $this->functionHooks as $tag => $bits ) { |
309 | 334 | list( $callback, $flags ) = $bits; |
310 | 335 | $parser->setFunctionHook( $tag, $callback, $flags ); |
311 | 336 | } |
| 337 | + |
312 | 338 | wfRunHooks( 'ParserTestParser', array( &$parser ) ); |
| 339 | + |
313 | 340 | return $parser; |
314 | 341 | } |
315 | 342 | |
— | — | @@ -369,15 +396,21 @@ |
370 | 397 | $out = $output->getText(); |
371 | 398 | |
372 | 399 | if ( isset( $opts['showtitle'] ) ) { |
373 | | - if ( $output->getTitleText() ) $title = $output->getTitleText(); |
| 400 | + if ( $output->getTitleText() ) { |
| 401 | + $title = $output->getTitleText(); |
| 402 | + } |
| 403 | + |
374 | 404 | $out = "$title\n$out"; |
375 | 405 | } |
| 406 | + |
376 | 407 | if ( isset( $opts['ill'] ) ) { |
377 | 408 | $out = $this->tidy( implode( ' ', $output->getLanguageLinks() ) ); |
378 | 409 | } elseif ( isset( $opts['cat'] ) ) { |
379 | 410 | global $wgOut; |
| 411 | + |
380 | 412 | $wgOut->addCategoryLinks( $output->getCategories() ); |
381 | 413 | $cats = $wgOut->getCategoryLinks(); |
| 414 | + |
382 | 415 | if ( isset( $cats['normal'] ) ) { |
383 | 416 | $out = $this->tidy( implode( ' ', $cats['normal'] ) ); |
384 | 417 | } else { |
— | — | @@ -398,7 +431,6 @@ |
399 | 432 | } |
400 | 433 | } |
401 | 434 | |
402 | | - |
403 | 435 | /** |
404 | 436 | * Use a regex to find out the value of an option |
405 | 437 | * @param $key String: name of option val to retrieve |
— | — | @@ -407,6 +439,7 @@ |
408 | 440 | */ |
409 | 441 | private static function getOptionValue( $key, $opts, $default ) { |
410 | 442 | $key = strtolower( $key ); |
| 443 | + |
411 | 444 | if ( isset( $opts[$key] ) ) { |
412 | 445 | return $opts[$key]; |
413 | 446 | } else { |
— | — | @@ -474,6 +507,7 @@ |
475 | 508 | if ( substr( $opt, 0, 1 ) == '"' ) { |
476 | 509 | return substr( $opt, 1, -1 ); |
477 | 510 | } |
| 511 | + |
478 | 512 | if ( substr( $opt, 0, 2 ) == '[[' ) { |
479 | 513 | return substr( $opt, 2, -2 ); |
480 | 514 | } |
— | — | @@ -565,12 +599,15 @@ |
566 | 600 | } |
567 | 601 | |
568 | 602 | $this->savedGlobals = array(); |
| 603 | + |
569 | 604 | foreach ( $settings as $var => $val ) { |
570 | 605 | if ( array_key_exists( $var, $GLOBALS ) ) { |
571 | 606 | $this->savedGlobals[$var] = $GLOBALS[$var]; |
572 | 607 | } |
| 608 | + |
573 | 609 | $GLOBALS[$var] = $val; |
574 | 610 | } |
| 611 | + |
575 | 612 | $langObj = Language::factory( $lang ); |
576 | 613 | $GLOBALS['wgLang'] = $langObj; |
577 | 614 | $GLOBALS['wgContLang'] = $langObj; |
— | — | @@ -578,6 +615,7 @@ |
579 | 616 | $GLOBALS['wgOut'] = new OutputPage; |
580 | 617 | |
581 | 618 | global $wgHooks; |
| 619 | + |
582 | 620 | $wgHooks['ParserTestParser'][] = 'ParserTestParserHook::setup'; |
583 | 621 | $wgHooks['ParserTestParser'][] = 'ParserTestStaticParserHook::setup'; |
584 | 622 | $wgHooks['ParserGetVariableValueTs'][] = 'ParserTest::getFakeTimestamp'; |
— | — | @@ -594,6 +632,7 @@ |
595 | 633 | */ |
596 | 634 | private function listTables() { |
597 | 635 | global $wgDBtype; |
| 636 | + |
598 | 637 | $tables = array( 'user', 'user_properties', 'page', 'page_restrictions', |
599 | 638 | 'protected_titles', 'revision', 'text', 'pagelinks', 'imagelinks', |
600 | 639 | 'categorylinks', 'templatelinks', 'externallinks', 'langlinks', 'iwlinks', |
— | — | @@ -621,12 +660,15 @@ |
622 | 661 | */ |
623 | 662 | public function setupDatabase() { |
624 | 663 | global $wgDBprefix, $wgDBtype; |
| 664 | + |
625 | 665 | if ( $this->databaseSetupDone ) { |
626 | 666 | return; |
627 | 667 | } |
| 668 | + |
628 | 669 | if ( $wgDBprefix === 'parsertest_' || ( $wgDBtype == 'oracle' && $wgDBprefix === 'pt_' ) ) { |
629 | 670 | throw new MWException( 'setupDatabase should be called before setupGlobals' ); |
630 | 671 | } |
| 672 | + |
631 | 673 | $this->databaseSetupDone = true; |
632 | 674 | $this->oldTablePrefix = $wgDBprefix; |
633 | 675 | |
— | — | @@ -663,9 +705,11 @@ |
664 | 706 | } elseif ( $db->tableExists( $tbl ) ) { |
665 | 707 | $db->query( "DROP TABLE $newTableName" ); |
666 | 708 | } |
| 709 | + |
667 | 710 | # Create new table |
668 | 711 | $db->duplicateTableStructure( $oldTableName, $newTableName, $temporary ); |
669 | 712 | } |
| 713 | + |
670 | 714 | if ( $wgDBtype == 'oracle' ) |
671 | 715 | $db->query( 'BEGIN FILL_WIKI_INFO; END;' ); |
672 | 716 | |
— | — | @@ -737,7 +781,7 @@ |
738 | 782 | 'media_type' => MEDIATYPE_BITMAP, |
739 | 783 | 'mime' => 'image/jpeg', |
740 | 784 | 'metadata' => serialize( array() ), |
741 | | - 'sha1' => sha1(''), |
| 785 | + 'sha1' => sha1( '' ), |
742 | 786 | 'fileExists' => true |
743 | 787 | ), $db->timestamp( '20010115123500' ), $user ); |
744 | 788 | |
— | — | @@ -751,7 +795,7 @@ |
752 | 796 | 'media_type' => MEDIATYPE_BITMAP, |
753 | 797 | 'mime' => 'image/jpeg', |
754 | 798 | 'metadata' => serialize( array() ), |
755 | | - 'sha1' => sha1(''), |
| 799 | + 'sha1' => sha1( '' ), |
756 | 800 | 'fileExists' => true |
757 | 801 | ), $db->timestamp( '20010115123500' ), $user ); |
758 | 802 | } |
— | — | @@ -775,6 +819,7 @@ |
776 | 820 | |
777 | 821 | public function teardownDatabase() { |
778 | 822 | global $wgDBtype; |
| 823 | + |
779 | 824 | if ( !$this->databaseSetupDone ) { |
780 | 825 | return; |
781 | 826 | } |
— | — | @@ -782,6 +827,7 @@ |
783 | 828 | |
784 | 829 | $this->changePrefix( $this->oldTablePrefix ); |
785 | 830 | $this->databaseSetupDone = false; |
| 831 | + |
786 | 832 | if ( $this->useTemporaryTables ) { |
787 | 833 | # Don't need to do anything |
788 | 834 | return; |
— | — | @@ -789,12 +835,14 @@ |
790 | 836 | |
791 | 837 | $tables = $this->listTables(); |
792 | 838 | $db = wfGetDB( DB_MASTER ); |
| 839 | + |
793 | 840 | foreach ( $tables as $table ) { |
794 | 841 | $sql = $wgDBtype == 'oracle' ? "DROP TABLE pt_$table DROP CONSTRAINTS" : "DROP TABLE `parsertest_$table`"; |
795 | 842 | $db->query( $sql ); |
796 | 843 | } |
797 | | - if ($wgDBtype == 'oracle') |
798 | | - $db->query('BEGIN FILL_WIKI_INFO; END;'); |
| 844 | + |
| 845 | + if ( $wgDBtype == 'oracle' ) |
| 846 | + $db->query( 'BEGIN FILL_WIKI_INFO; END;' ); |
799 | 847 | } |
800 | 848 | |
801 | 849 | /** |
— | — | @@ -805,8 +853,10 @@ |
806 | 854 | */ |
807 | 855 | private function setupUploadDir() { |
808 | 856 | global $IP; |
| 857 | + |
809 | 858 | if ( $this->keepUploads ) { |
810 | 859 | $dir = wfTempDir() . '/mwParser-images'; |
| 860 | + |
811 | 861 | if ( is_dir( $dir ) ) { |
812 | 862 | return $dir; |
813 | 863 | } |
— | — | @@ -814,15 +864,17 @@ |
815 | 865 | $dir = wfTempDir() . "/mwParser-" . mt_rand() . "-images"; |
816 | 866 | } |
817 | 867 | |
818 | | - //wfDebug( "Creating upload directory $dir\n" ); |
| 868 | + // wfDebug( "Creating upload directory $dir\n" ); |
819 | 869 | if ( file_exists( $dir ) ) { |
820 | 870 | wfDebug( "Already exists!\n" ); |
821 | 871 | return $dir; |
822 | 872 | } |
| 873 | + |
823 | 874 | wfMkdirParents( $dir . '/3/3a' ); |
824 | 875 | copy( "$IP/skins/monobook/headbg.jpg", "$dir/3/3a/Foobar.jpg" ); |
825 | 876 | wfMkdirParents( $dir . '/0/09' ); |
826 | 877 | copy( "$IP/skins/monobook/headbg.jpg", "$dir/0/09/Bad.jpg" ); |
| 878 | + |
827 | 879 | return $dir; |
828 | 880 | } |
829 | 881 | |
— | — | @@ -833,6 +885,7 @@ |
834 | 886 | private function teardownGlobals() { |
835 | 887 | RepoGroup::destroySingleton(); |
836 | 888 | LinkCache::singleton()->clear(); |
| 889 | + |
837 | 890 | foreach ( $this->savedGlobals as $var => $val ) { |
838 | 891 | $GLOBALS[$var] = $val; |
839 | 892 | } |
— | — | @@ -924,6 +977,7 @@ |
925 | 978 | if ( $this->showProgress ) { |
926 | 979 | print $this->term->color( '1;32' ) . 'PASSED' . $this->term->reset() . "\n"; |
927 | 980 | } |
| 981 | + |
928 | 982 | return true; |
929 | 983 | } |
930 | 984 | |
— | — | @@ -943,10 +997,13 @@ |
944 | 998 | # test, in case it succeeded. Show it now: |
945 | 999 | $this->showTesting( $desc ); |
946 | 1000 | } |
| 1001 | + |
947 | 1002 | print $this->term->color( '31' ) . 'FAILED!' . $this->term->reset() . "\n"; |
| 1003 | + |
948 | 1004 | if ( $this->showOutput ) { |
949 | 1005 | print "--- Expected ---\n$result\n--- Actual ---\n$html\n"; |
950 | 1006 | } |
| 1007 | + |
951 | 1008 | if ( $this->showDiffs ) { |
952 | 1009 | print $this->quickDiff( $result, $html ); |
953 | 1010 | if ( !$this->wellFormed( $html ) ) { |
— | — | @@ -954,6 +1011,7 @@ |
955 | 1012 | } |
956 | 1013 | } |
957 | 1014 | } |
| 1015 | + |
958 | 1016 | return false; |
959 | 1017 | } |
960 | 1018 | |
— | — | @@ -1034,11 +1092,13 @@ |
1035 | 1093 | $wgCapitalLinks = true; // We only need this from SetupGlobals() See r70917#c8637 |
1036 | 1094 | |
1037 | 1095 | $title = Title::newFromText( $name ); |
| 1096 | + |
1038 | 1097 | if ( is_null( $title ) ) { |
1039 | 1098 | wfDie( "invalid title at line $line\n" ); |
1040 | 1099 | } |
1041 | 1100 | |
1042 | 1101 | $aid = $title->getArticleID( GAID_FOR_UPDATE ); |
| 1102 | + |
1043 | 1103 | if ( $aid != 0 ) { |
1044 | 1104 | wfDie( "duplicate article '$name' at line $line\n" ); |
1045 | 1105 | } |
— | — | @@ -1059,13 +1119,16 @@ |
1060 | 1120 | */ |
1061 | 1121 | public function requireHook( $name ) { |
1062 | 1122 | global $wgParser; |
| 1123 | + |
1063 | 1124 | $wgParser->firstCallInit( ); // make sure hooks are loaded. |
| 1125 | + |
1064 | 1126 | if ( isset( $wgParser->mTagHooks[$name] ) ) { |
1065 | 1127 | $this->hooks[$name] = $wgParser->mTagHooks[$name]; |
1066 | 1128 | } else { |
1067 | 1129 | echo " This test suite requires the '$name' hook extension, skipping.\n"; |
1068 | 1130 | return false; |
1069 | 1131 | } |
| 1132 | + |
1070 | 1133 | return true; |
1071 | 1134 | } |
1072 | 1135 | |
— | — | @@ -1079,13 +1142,16 @@ |
1080 | 1143 | */ |
1081 | 1144 | public function requireFunctionHook( $name ) { |
1082 | 1145 | global $wgParser; |
| 1146 | + |
1083 | 1147 | $wgParser->firstCallInit( ); // make sure hooks are loaded. |
| 1148 | + |
1084 | 1149 | if ( isset( $wgParser->mFunctionHooks[$name] ) ) { |
1085 | 1150 | $this->functionHooks[$name] = $wgParser->mFunctionHooks[$name]; |
1086 | 1151 | } else { |
1087 | 1152 | echo " This test suite requires the '$name' function hook extension, skipping.\n"; |
1088 | 1153 | return false; |
1089 | 1154 | } |
| 1155 | + |
1090 | 1156 | return true; |
1091 | 1157 | } |
1092 | 1158 | |
— | — | @@ -1099,9 +1165,11 @@ |
1100 | 1166 | */ |
1101 | 1167 | private function tidy( $text ) { |
1102 | 1168 | global $wgUseTidy; |
| 1169 | + |
1103 | 1170 | if ( $wgUseTidy ) { |
1104 | 1171 | $text = MWTidy::tidy( $text ); |
1105 | 1172 | } |
| 1173 | + |
1106 | 1174 | return $text; |
1107 | 1175 | } |
1108 | 1176 | |
— | — | @@ -1123,9 +1191,12 @@ |
1124 | 1192 | $fragment = $this->extractFragment( $html, $position ); |
1125 | 1193 | $this->mXmlError = "$err at byte $position:\n$fragment"; |
1126 | 1194 | xml_parser_free( $parser ); |
| 1195 | + |
1127 | 1196 | return false; |
1128 | 1197 | } |
| 1198 | + |
1129 | 1199 | xml_parser_free( $parser ); |
| 1200 | + |
1130 | 1201 | return true; |
1131 | 1202 | } |
1132 | 1203 | |
— | — | @@ -1150,6 +1221,7 @@ |
1151 | 1222 | $this->term->color( 31 ) . |
1152 | 1223 | '^' . |
1153 | 1224 | $this->term->color( 0 ); |
| 1225 | + |
1154 | 1226 | return "$display\n$caret"; |
1155 | 1227 | } |
1156 | 1228 | |
— | — | @@ -1171,7 +1243,9 @@ |
1172 | 1244 | */ |
1173 | 1245 | public function color( $color ) { |
1174 | 1246 | global $wgCommandLineDarkBg; |
| 1247 | + |
1175 | 1248 | $light = $wgCommandLineDarkBg ? "1;" : "0;"; |
| 1249 | + |
1176 | 1250 | return "\x1b[{$light}{$color}m"; |
1177 | 1251 | } |
1178 | 1252 | |
— | — | @@ -1230,13 +1304,16 @@ |
1231 | 1305 | function reportPercentage( $success, $total ) { |
1232 | 1306 | $ratio = wfPercent( 100 * $success / $total ); |
1233 | 1307 | print $this->term->color( 1 ) . "Passed $success of $total tests ($ratio)... "; |
| 1308 | + |
1234 | 1309 | if ( $success == $total ) { |
1235 | 1310 | print $this->term->color( 32 ) . "ALL TESTS PASSED!"; |
1236 | 1311 | } else { |
1237 | 1312 | $failed = $total - $success ; |
1238 | 1313 | print $this->term->color( 31 ) . "$failed tests failed!"; |
1239 | 1314 | } |
| 1315 | + |
1240 | 1316 | print $this->term->reset() . "\n"; |
| 1317 | + |
1241 | 1318 | return ( $success == $total ); |
1242 | 1319 | } |
1243 | 1320 | } |
— | — | @@ -1253,6 +1330,7 @@ |
1254 | 1331 | */ |
1255 | 1332 | function __construct( $parent ) { |
1256 | 1333 | parent::__construct( $parent ); |
| 1334 | + |
1257 | 1335 | $this->lb = wfGetLBFactory()->newMainLB(); |
1258 | 1336 | // This connection will have the wiki's table prefix, not parsertest_ |
1259 | 1337 | $this->db = $this->lb->getConnection( DB_MASTER ); |
— | — | @@ -1274,6 +1352,7 @@ |
1275 | 1353 | // We'll make comparisons against the previous run later... |
1276 | 1354 | $this->prevRun = $this->db->selectField( 'testrun', 'MAX(tr_id)' ); |
1277 | 1355 | } |
| 1356 | + |
1278 | 1357 | $this->results = array(); |
1279 | 1358 | } |
1280 | 1359 | |
— | — | @@ -1301,6 +1380,7 @@ |
1302 | 1381 | |
1303 | 1382 | $res = $this->db->select( 'testitem', array( 'ti_name', 'ti_success' ), |
1304 | 1383 | array( 'ti_run' => $this->prevRun ), __METHOD__ ); |
| 1384 | + |
1305 | 1385 | foreach ( $res as $row ) { |
1306 | 1386 | if ( !$this->parent->regex |
1307 | 1387 | || preg_match( "/{$this->parent->regex}/i", $row->ti_name ) ) |
— | — | @@ -1321,6 +1401,7 @@ |
1322 | 1402 | } else /* if ( $prevResults[$test] == 0 )*/ { |
1323 | 1403 | $before = 'f'; |
1324 | 1404 | } |
| 1405 | + |
1325 | 1406 | if ( !isset( $this->results[$test] ) ) { |
1326 | 1407 | $after = 'n'; |
1327 | 1408 | } elseif ( $this->results[$test] == 1 ) { |
— | — | @@ -1328,7 +1409,9 @@ |
1329 | 1410 | } else /*if ( $this->results[$test] == 0 ) */ { |
1330 | 1411 | $after = 'f'; |
1331 | 1412 | } |
| 1413 | + |
1332 | 1414 | $code = $before . $after; |
| 1415 | + |
1333 | 1416 | if ( isset( $table[$code] ) ) { |
1334 | 1417 | $breakdown[$code][$test] = $this->getTestStatusInfo( $test, $after ); |
1335 | 1418 | } |
— | — | @@ -1339,6 +1422,7 @@ |
1340 | 1423 | if ( !empty( $breakdown[$code] ) ) { |
1341 | 1424 | $count = count( $breakdown[$code] ); |
1342 | 1425 | printf( "\n%4d %s\n", $count, $label ); |
| 1426 | + |
1343 | 1427 | foreach ( $breakdown[$code] as $differing_test_name => $statusInfo ) { |
1344 | 1428 | print " * $differing_test_name [$statusInfo]\n"; |
1345 | 1429 | } |
— | — | @@ -1347,6 +1431,7 @@ |
1348 | 1432 | } else { |
1349 | 1433 | print "No previous test runs to compare against.\n"; |
1350 | 1434 | } |
| 1435 | + |
1351 | 1436 | print "\n"; |
1352 | 1437 | parent::report(); |
1353 | 1438 | } |
— | — | @@ -1357,7 +1442,6 @@ |
1358 | 1443 | * which have never passed (which are more change requests than regressions). |
1359 | 1444 | */ |
1360 | 1445 | private function getTestStatusInfo( $testname, $after ) { |
1361 | | - |
1362 | 1446 | // If we're looking at a test that has just been removed, then say when it first appeared. |
1363 | 1447 | if ( $after == 'n' ) { |
1364 | 1448 | $changedRun = $this->db->selectField ( 'testitem', |
— | — | @@ -1368,6 +1452,7 @@ |
1369 | 1453 | array( 'tr_date', 'tr_mw_version' ), |
1370 | 1454 | array( 'tr_id' => $changedRun ), |
1371 | 1455 | __METHOD__ ); |
| 1456 | + |
1372 | 1457 | return "First recorded appearance: " |
1373 | 1458 | . date( "d-M-Y H:i:s", strtotime ( $appear->tr_date ) ) |
1374 | 1459 | . ", " . $appear->tr_mw_version; |
— | — | @@ -1378,6 +1463,7 @@ |
1379 | 1464 | $conds = array( |
1380 | 1465 | 'ti_name' => $testname, |
1381 | 1466 | 'ti_success' => ( $after == 'f' ? "1" : "0" ) ); |
| 1467 | + |
1382 | 1468 | if ( $this->curRun ) { |
1383 | 1469 | $conds[] = "ti_run != " . $this->db->addQuotes ( $this->curRun ); |
1384 | 1470 | } |
— | — | @@ -1412,6 +1498,7 @@ |
1413 | 1499 | } else { |
1414 | 1500 | $postDate = 'now'; |
1415 | 1501 | } |
| 1502 | + |
1416 | 1503 | return ( $after == "f" ? "Introduced" : "Fixed" ) . " between " |
1417 | 1504 | . date( "d-M-Y H:i:s", strtotime ( $pre->tr_date ) ) . ", " . $pre->tr_mw_version |
1418 | 1505 | . " and $postDate"; |
— | — | @@ -1444,12 +1531,14 @@ |
1445 | 1532 | or ! $this->db->tableExists( 'testitem' ) ) |
1446 | 1533 | { |
1447 | 1534 | print "WARNING> `testrun` table not found in database. Trying to create table.\n"; |
1448 | | - if ( $wgDBtype === 'postgres' ) |
| 1535 | + if ( $wgDBtype === 'postgres' ) { |
1449 | 1536 | $this->db->sourceFile( dirname( __FILE__ ) . '/testRunner.postgres.sql' ); |
1450 | | - elseif ( $wgDBtype === 'oracle' ) |
| 1537 | + } elseif ( $wgDBtype === 'oracle' ) { |
1451 | 1538 | $this->db->sourceFile( dirname( __FILE__ ) . '/testRunner.ora.sql' ); |
1452 | | - else |
| 1539 | + } else { |
1453 | 1540 | $this->db->sourceFile( dirname( __FILE__ ) . '/testRunner.sql' ); |
| 1541 | + } |
| 1542 | + |
1454 | 1543 | echo "OK, resuming.\n"; |
1455 | 1544 | } |
1456 | 1545 | |
— | — | @@ -1464,10 +1553,11 @@ |
1465 | 1554 | 'tr_uname' => php_uname() |
1466 | 1555 | ), |
1467 | 1556 | __METHOD__ ); |
1468 | | - if ( $wgDBtype === 'postgres' ) |
| 1557 | + if ( $wgDBtype === 'postgres' ) { |
1469 | 1558 | $this->curRun = $this->db->currentSequenceValue( 'testrun_id_seq' ); |
1470 | | - else |
| 1559 | + } else { |
1471 | 1560 | $this->curRun = $this->db->insertId(); |
| 1561 | + } |
1472 | 1562 | } |
1473 | 1563 | |
1474 | 1564 | /** |
— | — | @@ -1478,6 +1568,7 @@ |
1479 | 1569 | */ |
1480 | 1570 | function record( $test, $result ) { |
1481 | 1571 | parent::record( $test, $result ); |
| 1572 | + |
1482 | 1573 | $this->db->insert( 'testitem', |
1483 | 1574 | array( |
1484 | 1575 | 'ti_run' => $this->curRun, |
— | — | @@ -1491,6 +1582,7 @@ |
1492 | 1583 | class RemoteTestRecorder extends TestRecorder { |
1493 | 1584 | function start() { |
1494 | 1585 | parent::start(); |
| 1586 | + |
1495 | 1587 | $this->results = array(); |
1496 | 1588 | $this->ping( 'running' ); |
1497 | 1589 | } |
— | — | @@ -1532,6 +1624,7 @@ |
1533 | 1625 | $revId, |
1534 | 1626 | $status, |
1535 | 1627 | ); |
| 1628 | + |
1536 | 1629 | if ( $status == "complete" ) { |
1537 | 1630 | $message[] = $jsonResults; |
1538 | 1631 | } |
— | — | @@ -1546,21 +1639,26 @@ |
1547 | 1640 | 'status' => $status, |
1548 | 1641 | 'hmac' => $hmac, |
1549 | 1642 | ); |
| 1643 | + |
1550 | 1644 | if ( $status == "complete" ) { |
1551 | 1645 | $postData['results'] = $jsonResults; |
1552 | 1646 | } |
| 1647 | + |
1553 | 1648 | $response = $this->post( $remote['api-url'], $postData ); |
1554 | 1649 | |
1555 | 1650 | if ( $response === false ) { |
1556 | 1651 | print "CodeReview info upload failed to reach server.\n"; |
1557 | 1652 | exit( 1 ); |
1558 | 1653 | } |
| 1654 | + |
1559 | 1655 | $responseData = FormatJson::decode( $response, true ); |
| 1656 | + |
1560 | 1657 | if ( !is_array( $responseData ) ) { |
1561 | 1658 | print "CodeReview API response not recognized...\n"; |
1562 | 1659 | wfDebug( "Unrecognized CodeReview API response: $response\n" ); |
1563 | 1660 | exit( 1 ); |
1564 | 1661 | } |
| 1662 | + |
1565 | 1663 | if ( isset( $responseData['error'] ) ) { |
1566 | 1664 | $code = $responseData['error']['code']; |
1567 | 1665 | $info = $responseData['error']['info']; |
— | — | @@ -1588,13 +1686,17 @@ |
1589 | 1687 | |
1590 | 1688 | $this->file = $file; |
1591 | 1689 | $this->fh = fopen( $this->file, "rt" ); |
| 1690 | + |
1592 | 1691 | if ( !$this->fh ) { |
1593 | 1692 | wfDie( "Couldn't open file '$file'\n" ); |
1594 | 1693 | } |
1595 | 1694 | |
1596 | 1695 | $this->parser = $parser; |
1597 | 1696 | |
1598 | | - if ( $this->parser ) $this->parser->showRunFile( wfRelativePath( $this->file, $IP ) ); |
| 1697 | + if ( $this->parser ) { |
| 1698 | + $this->parser->showRunFile( wfRelativePath( $this->file, $IP ) ); |
| 1699 | + } |
| 1700 | + |
1599 | 1701 | $this->lineNum = $this->index = 0; |
1600 | 1702 | } |
1601 | 1703 | |
— | — | @@ -1606,6 +1708,7 @@ |
1607 | 1709 | if ( fseek( $this->fh, 0 ) ) { |
1608 | 1710 | wfDie( "Couldn't fseek to the start of '$this->file'\n" ); |
1609 | 1711 | } |
| 1712 | + |
1610 | 1713 | $this->index = -1; |
1611 | 1714 | $this->lineNum = 0; |
1612 | 1715 | $this->eof = false; |
— | — | @@ -1642,68 +1745,89 @@ |
1643 | 1746 | while ( false !== ( $line = fgets( $this->fh ) ) ) { |
1644 | 1747 | $this->lineNum++; |
1645 | 1748 | $matches = array(); |
| 1749 | + |
1646 | 1750 | if ( preg_match( '/^!!\s*(\w+)/', $line, $matches ) ) { |
1647 | 1751 | $section = strtolower( $matches[1] ); |
| 1752 | + |
1648 | 1753 | if ( $section == 'endarticle' ) { |
1649 | 1754 | if ( !isset( $data['text'] ) ) { |
1650 | 1755 | wfDie( "'endarticle' without 'text' at line {$this->lineNum} of $this->file\n" ); |
1651 | 1756 | } |
| 1757 | + |
1652 | 1758 | if ( !isset( $data['article'] ) ) { |
1653 | 1759 | wfDie( "'endarticle' without 'article' at line {$this->lineNum} of $this->file\n" ); |
1654 | 1760 | } |
| 1761 | + |
1655 | 1762 | if ( $this->parser ) { |
1656 | 1763 | $this->parser->addArticle( $this->parser->chomp( $data['article'] ), $this->parser->chomp( $data['text'] ), |
1657 | 1764 | $this->lineNum ); |
1658 | 1765 | } |
| 1766 | + |
1659 | 1767 | $data = array(); |
1660 | 1768 | $section = null; |
| 1769 | + |
1661 | 1770 | continue; |
1662 | 1771 | } |
| 1772 | + |
1663 | 1773 | if ( $section == 'endhooks' ) { |
1664 | 1774 | if ( !isset( $data['hooks'] ) ) { |
1665 | 1775 | wfDie( "'endhooks' without 'hooks' at line {$this->lineNum} of $this->file\n" ); |
1666 | 1776 | } |
| 1777 | + |
1667 | 1778 | foreach ( explode( "\n", $data['hooks'] ) as $line ) { |
1668 | 1779 | $line = trim( $line ); |
| 1780 | + |
1669 | 1781 | if ( $line ) { |
1670 | 1782 | if ( $this->parser && !$this->parser->requireHook( $line ) ) { |
1671 | 1783 | return false; |
1672 | 1784 | } |
1673 | 1785 | } |
1674 | 1786 | } |
| 1787 | + |
1675 | 1788 | $data = array(); |
1676 | 1789 | $section = null; |
| 1790 | + |
1677 | 1791 | continue; |
1678 | 1792 | } |
| 1793 | + |
1679 | 1794 | if ( $section == 'endfunctionhooks' ) { |
1680 | 1795 | if ( !isset( $data['functionhooks'] ) ) { |
1681 | 1796 | wfDie( "'endfunctionhooks' without 'functionhooks' at line {$this->lineNum} of $this->file\n" ); |
1682 | 1797 | } |
| 1798 | + |
1683 | 1799 | foreach ( explode( "\n", $data['functionhooks'] ) as $line ) { |
1684 | 1800 | $line = trim( $line ); |
| 1801 | + |
1685 | 1802 | if ( $line ) { |
1686 | 1803 | if ( $this->parser && !$this->parser->requireFunctionHook( $line ) ) { |
1687 | 1804 | return false; |
1688 | 1805 | } |
1689 | 1806 | } |
1690 | 1807 | } |
| 1808 | + |
1691 | 1809 | $data = array(); |
1692 | 1810 | $section = null; |
| 1811 | + |
1693 | 1812 | continue; |
1694 | 1813 | } |
| 1814 | + |
1695 | 1815 | if ( $section == 'end' ) { |
1696 | 1816 | if ( !isset( $data['test'] ) ) { |
1697 | 1817 | wfDie( "'end' without 'test' at line {$this->lineNum} of $this->file\n" ); |
1698 | 1818 | } |
| 1819 | + |
1699 | 1820 | if ( !isset( $data['input'] ) ) { |
1700 | 1821 | wfDie( "'end' without 'input' at line {$this->lineNum} of $this->file\n" ); |
1701 | 1822 | } |
| 1823 | + |
1702 | 1824 | if ( !isset( $data['result'] ) ) { |
1703 | 1825 | wfDie( "'end' without 'result' at line {$this->lineNum} of $this->file\n" ); |
1704 | 1826 | } |
| 1827 | + |
1705 | 1828 | if ( !isset( $data['options'] ) ) { |
1706 | 1829 | $data['options'] = ''; |
1707 | 1830 | } |
| 1831 | + |
1708 | 1832 | if ( !isset( $data['config'] ) ) |
1709 | 1833 | $data['config'] = ''; |
1710 | 1834 | |
— | — | @@ -1713,14 +1837,18 @@ |
1714 | 1838 | # disabled test |
1715 | 1839 | $data = array(); |
1716 | 1840 | $section = null; |
| 1841 | + |
1717 | 1842 | continue; |
1718 | 1843 | } |
| 1844 | + |
1719 | 1845 | global $wgUseTeX; |
| 1846 | + |
1720 | 1847 | if ( $this->parser && |
1721 | 1848 | preg_match( '/\\bmath\\b/i', $data['options'] ) && !$wgUseTeX ) { |
1722 | 1849 | # don't run math tests if $wgUseTeX is set to false in LocalSettings |
1723 | 1850 | $data = array(); |
1724 | 1851 | $section = null; |
| 1852 | + |
1725 | 1853 | continue; |
1726 | 1854 | } |
1727 | 1855 | |
— | — | @@ -1734,19 +1862,24 @@ |
1735 | 1863 | } else { |
1736 | 1864 | $this->test['test'] = $data['test']; |
1737 | 1865 | } |
| 1866 | + |
1738 | 1867 | return true; |
1739 | 1868 | } |
| 1869 | + |
1740 | 1870 | if ( isset ( $data[$section] ) ) { |
1741 | 1871 | wfDie( "duplicate section '$section' at line {$this->lineNum} of $this->file\n" ); |
1742 | 1872 | } |
| 1873 | + |
1743 | 1874 | $data[$section] = ''; |
| 1875 | + |
1744 | 1876 | continue; |
1745 | 1877 | } |
| 1878 | + |
1746 | 1879 | if ( $section ) { |
1747 | 1880 | $data[$section] .= $line; |
1748 | 1881 | } |
1749 | 1882 | } |
| 1883 | + |
1750 | 1884 | return false; |
1751 | 1885 | } |
1752 | 1886 | } |
1753 | | - |
Index: trunk/phase3/maintenance/tests/UploadFromUrlTestSuite.php |
— | — | @@ -1,13 +1,13 @@ |
2 | 2 | <?php |
3 | 3 | |
4 | | -class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite |
5 | | -{ |
| 4 | +class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite { |
6 | 5 | public static function addTables( &$tables ) { |
7 | 6 | $tables[] = 'user_properties'; |
8 | 7 | $tables[] = 'filearchive'; |
9 | 8 | $tables[] = 'logging'; |
10 | 9 | $tables[] = 'updatelog'; |
11 | 10 | $tables[] = 'iwlinks'; |
| 11 | + |
12 | 12 | return true; |
13 | 13 | } |
14 | 14 | |
— | — | @@ -28,9 +28,9 @@ |
29 | 29 | $wgLocalFileRepo = array( |
30 | 30 | 'class' => 'LocalRepo', |
31 | 31 | 'name' => 'local', |
32 | | - 'directory' => wfTempDir().'/test-repo', |
| 32 | + 'directory' => wfTempDir() . '/test-repo', |
33 | 33 | 'url' => 'http://example.com/images', |
34 | | - 'deletedDir' => wfTempDir().'/test-repo/delete', |
| 34 | + 'deletedDir' => wfTempDir() . '/test-repo/delete', |
35 | 35 | 'hashLevels' => 2, |
36 | 36 | 'transformVia404' => false, |
37 | 37 | ); |
— | — | @@ -45,7 +45,7 @@ |
46 | 46 | $messageMemc =& wfGetMessageCacheStorage(); |
47 | 47 | $parserMemc =& wfGetParserCacheStorage(); |
48 | 48 | |
49 | | - //$wgContLang = new StubContLang; |
| 49 | + // $wgContLang = new StubContLang; |
50 | 50 | $wgUser = new User; |
51 | 51 | $wgLang = new StubUserLang; |
52 | 52 | $wgOut = new StubObject( 'wgOut', 'OutputPage' ); |
— | — | @@ -55,7 +55,9 @@ |
56 | 56 | $wgMessageCache = new StubObject( 'wgMessageCache', 'MessageCache', |
57 | 57 | array( $messageMemc, $wgUseDatabaseMessages, |
58 | 58 | $wgMsgCacheExpiry ) ); |
59 | | - if ( $wgStyleDirectory === false ) $wgStyleDirectory = "$IP/skins"; |
| 59 | + if ( $wgStyleDirectory === false ) { |
| 60 | + $wgStyleDirectory = "$IP/skins"; |
| 61 | + } |
60 | 62 | |
61 | 63 | } |
62 | 64 | |
— | — | @@ -106,7 +108,6 @@ |
107 | 109 | ); |
108 | 110 | } |
109 | 111 | |
110 | | - |
111 | 112 | /** |
112 | 113 | * Delete the specified files, if they exist. |
113 | 114 | * |
— | — | @@ -141,8 +142,10 @@ |
142 | 143 | */ |
143 | 144 | private function setupUploadDir() { |
144 | 145 | global $IP; |
| 146 | + |
145 | 147 | if ( $this->keepUploads ) { |
146 | 148 | $dir = wfTempDir() . '/mwParser-images'; |
| 149 | + |
147 | 150 | if ( is_dir( $dir ) ) { |
148 | 151 | return $dir; |
149 | 152 | } |
— | — | @@ -151,22 +154,22 @@ |
152 | 155 | } |
153 | 156 | |
154 | 157 | wfDebug( "Creating upload directory $dir\n" ); |
| 158 | + |
155 | 159 | if ( file_exists( $dir ) ) { |
156 | 160 | wfDebug( "Already exists!\n" ); |
157 | 161 | return $dir; |
158 | 162 | } |
| 163 | + |
159 | 164 | wfMkdirParents( $dir . '/3/3a' ); |
160 | 165 | copy( "$IP/skins/monobook/headbg.jpg", "$dir/3/3a/Foobar.jpg" ); |
161 | 166 | |
162 | 167 | wfMkdirParents( $dir . '/0/09' ); |
163 | 168 | copy( "$IP/skins/monobook/headbg.jpg", "$dir/0/09/Bad.jpg" ); |
| 169 | + |
164 | 170 | return $dir; |
165 | 171 | } |
166 | 172 | |
167 | | - public static function suite() |
168 | | - { |
| 173 | + public static function suite() { |
169 | 174 | return new UploadFromUrlTestSuite( 'UploadFromUrlTest' ); |
170 | 175 | } |
171 | | - |
172 | 176 | } |
173 | | - |
Index: trunk/phase3/maintenance/tests/selenium/SeleniumTestSuite.php |
— | — | @@ -11,7 +11,7 @@ |
12 | 12 | |
13 | 13 | public function setUp() { |
14 | 14 | // Hack because because PHPUnit version 3.0.6 which is on prototype does not |
15 | | - //run setUp as part of TestSuite::run |
| 15 | + // run setUp as part of TestSuite::run |
16 | 16 | if ( $this->isSetUp ) { |
17 | 17 | return; |
18 | 18 | } |
— | — | @@ -34,4 +34,3 @@ |
35 | 35 | $this->selenium->loadPage( $title, $action ); |
36 | 36 | } |
37 | 37 | } |
38 | | - |
Index: trunk/phase3/maintenance/tests/selenium/Selenium.php |
— | — | @@ -5,6 +5,7 @@ |
6 | 6 | */ |
7 | 7 | |
8 | 8 | require( 'Testing/Selenium.php' ); |
| 9 | + |
9 | 10 | class Selenium { |
10 | 11 | protected static $_instance = null; |
11 | 12 | public $isStarted = false; |
— | — | @@ -36,7 +37,7 @@ |
37 | 38 | if ( null === self::$_instance ) { |
38 | 39 | self::$_instance = $this; |
39 | 40 | } else { |
40 | | - throw new MWException("Already have one Selenium instance."); |
| 41 | + throw new MWException( "Already have one Selenium instance." ); |
41 | 42 | } |
42 | 43 | } |
43 | 44 | |
— | — | @@ -75,9 +76,11 @@ |
76 | 77 | $this->type( 'wpName1', $this->user ); |
77 | 78 | $this->type( 'wpPassword1', $this->pass ); |
78 | 79 | $this->click( "//input[@id='wpLoginAttempt']" ); |
79 | | - $this->waitForPageToLoad(5000); |
80 | | - //after login we redirect to the main page. So check whether the "Prefernces" top menu item exists |
| 80 | + $this->waitForPageToLoad( 5000 ); |
| 81 | + |
| 82 | + // after login we redirect to the main page. So check whether the "Prefernces" top menu item exists |
81 | 83 | $value = $this->isElementPresent( "//li[@id='pt-preferences']" ); |
| 84 | + |
82 | 85 | if ( $value != true ) { |
83 | 86 | throw new Testing_Selenium_Exception( "Login Failed" ); |
84 | 87 | } |
— | — | @@ -95,7 +98,7 @@ |
96 | 99 | public function loadPage( $title, $action ) { |
97 | 100 | $this->open( self::$url . '/index.php?title=' . $title . '&action=' . $action ); |
98 | 101 | } |
99 | | - |
| 102 | + |
100 | 103 | public function setLogger( $logger ) { |
101 | 104 | $this->logger = $logger; |
102 | 105 | } |
— | — | @@ -138,14 +141,17 @@ |
139 | 142 | |
140 | 143 | public function setBrowser( $b ) { |
141 | 144 | $browsers = $this->setupBrowsers(); |
| 145 | + |
| 146 | + |
142 | 147 | if ( !isset( $browsers[$b] ) ) { |
143 | 148 | throw new MWException( "Invalid Browser: $b.\n" ); |
144 | 149 | } |
| 150 | + |
145 | 151 | $this->browser = $browsers[$b]; |
146 | 152 | } |
147 | 153 | |
148 | 154 | public function __call( $name, $args ) { |
149 | | - $t = call_user_func_array( array( $this->tester, $name), $args ); |
| 155 | + $t = call_user_func_array( array( $this->tester, $name ), $args ); |
150 | 156 | return $t; |
151 | 157 | } |
152 | 158 | |
— | — | @@ -179,14 +185,16 @@ |
180 | 186 | |
181 | 187 | public function setBrowser( $b ) { |
182 | 188 | $browsers = $this->setupBrowsers(); |
| 189 | + |
183 | 190 | if ( !isset( $browsers[$b] ) ) { |
184 | 191 | throw new MWException( "Invalid Browser: $b.\n" ); |
185 | 192 | } |
| 193 | + |
186 | 194 | $this->browser = $browsers[$b]; |
187 | 195 | } |
188 | 196 | |
189 | 197 | public function __call( $name, $args ) { |
190 | | - $t = call_user_func_array( array( $this->tester, $name), $args ); |
| 198 | + $t = call_user_func_array( array( $this->tester, $name ), $args ); |
191 | 199 | return $t; |
192 | 200 | } |
193 | 201 | |
Index: trunk/phase3/includes/db/Database.php |
— | — | @@ -21,9 +21,9 @@ |
22 | 22 | */ |
23 | 23 | abstract class DatabaseBase implements DatabaseType { |
24 | 24 | |
25 | | -#------------------------------------------------------------------------------ |
| 25 | +# ------------------------------------------------------------------------------ |
26 | 26 | # Variables |
27 | | -#------------------------------------------------------------------------------ |
| 27 | +# ------------------------------------------------------------------------------ |
28 | 28 | |
29 | 29 | protected $mLastQuery = ''; |
30 | 30 | protected $mDoneWrites = false; |
— | — | @@ -41,9 +41,9 @@ |
42 | 42 | protected $mFakeSlaveLag = null, $mFakeMaster = false; |
43 | 43 | protected $mDefaultBigSelects = null; |
44 | 44 | |
45 | | -#------------------------------------------------------------------------------ |
| 45 | +# ------------------------------------------------------------------------------ |
46 | 46 | # Accessors |
47 | | -#------------------------------------------------------------------------------ |
| 47 | +# ------------------------------------------------------------------------------ |
48 | 48 | # These optionally set a variable and return the previous state |
49 | 49 | |
50 | 50 | /** |
— | — | @@ -258,7 +258,7 @@ |
259 | 259 | * @return Boolean |
260 | 260 | */ |
261 | 261 | function getFlag( $flag ) { |
262 | | - return !!($this->mFlags & $flag); |
| 262 | + return !!( $this->mFlags & $flag ); |
263 | 263 | } |
264 | 264 | |
265 | 265 | /** |
— | — | @@ -269,7 +269,7 @@ |
270 | 270 | } |
271 | 271 | |
272 | 272 | function getWikiID() { |
273 | | - if( $this->mTablePrefix ) { |
| 273 | + if ( $this->mTablePrefix ) { |
274 | 274 | return "{$this->mDBname}-{$this->mTablePrefix}"; |
275 | 275 | } else { |
276 | 276 | return $this->mDBname; |
— | — | @@ -288,9 +288,9 @@ |
289 | 289 | } |
290 | 290 | } |
291 | 291 | |
292 | | -#------------------------------------------------------------------------------ |
| 292 | +# ------------------------------------------------------------------------------ |
293 | 293 | # Other functions |
294 | | -#------------------------------------------------------------------------------ |
| 294 | +# ------------------------------------------------------------------------------ |
295 | 295 | |
296 | 296 | /** |
297 | 297 | * Constructor. |
— | — | @@ -303,9 +303,10 @@ |
304 | 304 | * @param $tablePrefix String: database table prefixes. By default use the prefix gave in LocalSettings.php |
305 | 305 | */ |
306 | 306 | function __construct( $server = false, $user = false, $password = false, $dbName = false, |
307 | | - $failFunction = false, $flags = 0, $tablePrefix = 'get from global' ) { |
| 307 | + $failFunction = false, $flags = 0, $tablePrefix = 'get from global' |
| 308 | + ) { |
| 309 | + global $wgOut, $wgDBprefix, $wgCommandLineMode; |
308 | 310 | |
309 | | - global $wgOut, $wgDBprefix, $wgCommandLineMode; |
310 | 311 | # Can't get a reference if it hasn't been set yet |
311 | 312 | if ( !isset( $wgOut ) ) { |
312 | 313 | $wgOut = null; |
— | — | @@ -350,8 +351,7 @@ |
351 | 352 | * @param failFunction |
352 | 353 | * @param $flags |
353 | 354 | */ |
354 | | - static function newFromParams( $server, $user, $password, $dbName, $failFunction = false, $flags = 0 ) |
355 | | - { |
| 355 | + static function newFromParams( $server, $user, $password, $dbName, $failFunction = false, $flags = 0 ) { |
356 | 356 | wfDeprecated( __METHOD__ ); |
357 | 357 | return new DatabaseMysql( $server, $user, $password, $dbName, $failFunction, $flags ); |
358 | 358 | } |
— | — | @@ -441,7 +441,7 @@ |
442 | 442 | # logging size most of the time. The substr is really just a sanity check. |
443 | 443 | |
444 | 444 | # Who's been wasting my precious column space? -- TS |
445 | | - #$profName = 'query: ' . $fname . ' ' . substr( DatabaseBase::generalizeSQL( $sql ), 0, 255 ); |
| 445 | + # $profName = 'query: ' . $fname . ' ' . substr( DatabaseBase::generalizeSQL( $sql ), 0, 255 ); |
446 | 446 | |
447 | 447 | if ( $isMaster ) { |
448 | 448 | $queryProf = 'query-m: ' . substr( DatabaseBase::generalizeSQL( $sql ), 0, 255 ); |
— | — | @@ -450,6 +450,7 @@ |
451 | 451 | $queryProf = 'query: ' . substr( DatabaseBase::generalizeSQL( $sql ), 0, 255 ); |
452 | 452 | $totalProf = 'DatabaseBase::query'; |
453 | 453 | } |
| 454 | + |
454 | 455 | wfProfileIn( $totalProf ); |
455 | 456 | wfProfileIn( $queryProf ); |
456 | 457 | } |
— | — | @@ -457,14 +458,14 @@ |
458 | 459 | $this->mLastQuery = $sql; |
459 | 460 | if ( !$this->mDoneWrites && $this->isWriteQuery( $sql ) ) { |
460 | 461 | // Set a flag indicating that writes have been done |
461 | | - wfDebug( __METHOD__.": Writes done: $sql\n" ); |
| 462 | + wfDebug( __METHOD__ . ": Writes done: $sql\n" ); |
462 | 463 | $this->mDoneWrites = true; |
463 | 464 | } |
464 | 465 | |
465 | 466 | # Add a comment for easy SHOW PROCESSLIST interpretation |
466 | | - #if ( $fname ) { |
| 467 | + # if ( $fname ) { |
467 | 468 | global $wgUser; |
468 | | - if ( is_object( $wgUser ) && !($wgUser instanceof StubObject) ) { |
| 469 | + if ( is_object( $wgUser ) && !( $wgUser instanceof StubObject ) ) { |
469 | 470 | $userName = $wgUser->getName(); |
470 | 471 | if ( mb_strlen( $userName ) > 15 ) { |
471 | 472 | $userName = mb_substr( $userName, 0, 15 ) . '...'; |
— | — | @@ -473,27 +474,29 @@ |
474 | 475 | } else { |
475 | 476 | $userName = ''; |
476 | 477 | } |
477 | | - $commentedSql = preg_replace('/\s/', " /* $fname $userName */ ", $sql, 1); |
478 | | - #} else { |
| 478 | + $commentedSql = preg_replace( '/\s/', " /* $fname $userName */ ", $sql, 1 ); |
| 479 | + # } else { |
479 | 480 | # $commentedSql = $sql; |
480 | | - #} |
| 481 | + # } |
481 | 482 | |
482 | 483 | # If DBO_TRX is set, start a transaction |
483 | 484 | if ( ( $this->mFlags & DBO_TRX ) && !$this->trxLevel() && |
484 | | - $sql != 'BEGIN' && $sql != 'COMMIT' && $sql != 'ROLLBACK') { |
| 485 | + $sql != 'BEGIN' && $sql != 'COMMIT' && $sql != 'ROLLBACK' ) { |
485 | 486 | // avoid establishing transactions for SHOW and SET statements too - |
486 | 487 | // that would delay transaction initializations to once connection |
487 | 488 | // is really used by application |
488 | | - $sqlstart = substr($sql,0,10); // very much worth it, benchmark certified(tm) |
489 | | - if (strpos($sqlstart,"SHOW ")!==0 and strpos($sqlstart,"SET ")!==0) |
| 489 | + $sqlstart = substr( $sql, 0, 10 ); // very much worth it, benchmark certified(tm) |
| 490 | + if ( strpos( $sqlstart, "SHOW " ) !== 0 and strpos( $sqlstart, "SET " ) !== 0 ) |
490 | 491 | $this->begin(); |
491 | 492 | } |
492 | 493 | |
493 | 494 | if ( $this->debug() ) { |
494 | 495 | static $cnt = 0; |
| 496 | + |
495 | 497 | $cnt++; |
496 | 498 | $sqlx = substr( $commentedSql, 0, 500 ); |
497 | 499 | $sqlx = strtr( $sqlx, "\t\n", ' ' ); |
| 500 | + |
498 | 501 | if ( $isMaster ) { |
499 | 502 | wfDebug( "Query $cnt (master): $sqlx\n" ); |
500 | 503 | } else { |
— | — | @@ -513,12 +516,13 @@ |
514 | 517 | # Transaction is gone, like it or not |
515 | 518 | $this->mTrxLevel = 0; |
516 | 519 | wfDebug( "Connection lost, reconnecting...\n" ); |
| 520 | + |
517 | 521 | if ( $this->ping() ) { |
518 | 522 | wfDebug( "Reconnected\n" ); |
519 | 523 | $sqlx = substr( $commentedSql, 0, 500 ); |
520 | 524 | $sqlx = strtr( $sqlx, "\t\n", ' ' ); |
521 | 525 | global $wgRequestTime; |
522 | | - $elapsed = round( microtime(true) - $wgRequestTime, 3 ); |
| 526 | + $elapsed = round( microtime( true ) - $wgRequestTime, 3 ); |
523 | 527 | wfLogDBError( "Connection lost and reconnected after {$elapsed}s, query: $sqlx\n" ); |
524 | 528 | $ret = $this->doQuery( $commentedSql ); |
525 | 529 | } else { |
— | — | @@ -534,6 +538,7 @@ |
535 | 539 | wfProfileOut( $queryProf ); |
536 | 540 | wfProfileOut( $totalProf ); |
537 | 541 | } |
| 542 | + |
538 | 543 | return $this->resultObject( $ret ); |
539 | 544 | } |
540 | 545 | |
— | — | @@ -549,13 +554,13 @@ |
550 | 555 | $ignore = $this->ignoreErrors( true ); |
551 | 556 | ++$this->mErrorCount; |
552 | 557 | |
553 | | - if( $ignore || $tempIgnore ) { |
554 | | - wfDebug("SQL ERROR (ignored): $error\n"); |
| 558 | + if ( $ignore || $tempIgnore ) { |
| 559 | + wfDebug( "SQL ERROR (ignored): $error\n" ); |
555 | 560 | $this->ignoreErrors( $ignore ); |
556 | 561 | } else { |
557 | 562 | $sql1line = str_replace( "\n", "\\n", $sql ); |
558 | | - wfLogDBError("$fname\t{$this->mServer}\t$errno\t$error\t$sql1line\n"); |
559 | | - wfDebug("SQL ERROR: " . $error . "\n"); |
| 563 | + wfLogDBError( "$fname\t{$this->mServer}\t$errno\t$error\t$sql1line\n" ); |
| 564 | + wfDebug( "SQL ERROR: " . $error . "\n" ); |
560 | 565 | throw new DBQueryError( $this, $error, $errno, $sql, $fname ); |
561 | 566 | } |
562 | 567 | } |
— | — | @@ -587,12 +592,14 @@ |
588 | 593 | * @param $args Mixed: Either an array here, or put scalars as varargs |
589 | 594 | */ |
590 | 595 | function execute( $prepared, $args = null ) { |
591 | | - if( !is_array( $args ) ) { |
| 596 | + if ( !is_array( $args ) ) { |
592 | 597 | # Pull the var args |
593 | 598 | $args = func_get_args(); |
594 | 599 | array_shift( $args ); |
595 | 600 | } |
| 601 | + |
596 | 602 | $sql = $this->fillPrepared( $prepared['query'], $args ); |
| 603 | + |
597 | 604 | return $this->query( $sql, $prepared['func'] ); |
598 | 605 | } |
599 | 606 | |
— | — | @@ -604,13 +611,16 @@ |
605 | 612 | */ |
606 | 613 | function safeQuery( $query, $args = null ) { |
607 | 614 | $prepared = $this->prepare( $query, 'DatabaseBase::safeQuery' ); |
608 | | - if( !is_array( $args ) ) { |
| 615 | + |
| 616 | + if ( !is_array( $args ) ) { |
609 | 617 | # Pull the var args |
610 | 618 | $args = func_get_args(); |
611 | 619 | array_shift( $args ); |
612 | 620 | } |
| 621 | + |
613 | 622 | $retval = $this->execute( $prepared, $args ); |
614 | 623 | $this->freePrepared( $prepared ); |
| 624 | + |
615 | 625 | return $retval; |
616 | 626 | } |
617 | 627 | |
— | — | @@ -624,6 +634,7 @@ |
625 | 635 | function fillPrepared( $preparedQuery, $args ) { |
626 | 636 | reset( $args ); |
627 | 637 | $this->preparedArgs =& $args; |
| 638 | + |
628 | 639 | return preg_replace_callback( '/(\\\\[?!&]|[?!&])/', |
629 | 640 | array( &$this, 'fillPreparedArg' ), $preparedQuery ); |
630 | 641 | } |
— | — | @@ -643,7 +654,9 @@ |
644 | 655 | case '\\!': return '!'; |
645 | 656 | case '\\&': return '&'; |
646 | 657 | } |
| 658 | + |
647 | 659 | list( /* $n */ , $arg ) = each( $this->preparedArgs ); |
| 660 | + |
648 | 661 | switch( $matches[1] ) { |
649 | 662 | case '?': return $this->addQuotes( $arg ); |
650 | 663 | case '!': return $arg; |
— | — | @@ -676,6 +689,7 @@ |
677 | 690 | $table = $this->tableName( $table ); |
678 | 691 | $sql = "UPDATE $table SET $var = '" . |
679 | 692 | $this->strencode( $value ) . "' WHERE ($cond)"; |
| 693 | + |
680 | 694 | return (bool)$this->query( $sql, $fname ); |
681 | 695 | } |
682 | 696 | |
— | — | @@ -684,17 +698,21 @@ |
685 | 699 | * Usually aborts on failure |
686 | 700 | * If errors are explicitly ignored, returns FALSE on failure |
687 | 701 | */ |
688 | | - function selectField( $table, $var, $cond='', $fname = 'DatabaseBase::selectField', $options = array() ) { |
| 702 | + function selectField( $table, $var, $cond = '', $fname = 'DatabaseBase::selectField', $options = array() ) { |
689 | 703 | if ( !is_array( $options ) ) { |
690 | 704 | $options = array( $options ); |
691 | 705 | } |
| 706 | + |
692 | 707 | $options['LIMIT'] = 1; |
693 | 708 | |
694 | 709 | $res = $this->select( $table, $var, $cond, $fname, $options ); |
| 710 | + |
695 | 711 | if ( $res === false || !$this->numRows( $res ) ) { |
696 | 712 | return false; |
697 | 713 | } |
| 714 | + |
698 | 715 | $row = $this->fetchRow( $res ); |
| 716 | + |
699 | 717 | if ( $row !== false ) { |
700 | 718 | return reset( $row ); |
701 | 719 | } else { |
— | — | @@ -717,6 +735,7 @@ |
718 | 736 | $startOpts = ''; |
719 | 737 | |
720 | 738 | $noKeyOptions = array(); |
| 739 | + |
721 | 740 | foreach ( $options as $key => $option ) { |
722 | 741 | if ( is_numeric( $key ) ) { |
723 | 742 | $noKeyOptions[$option] = true; |
— | — | @@ -726,25 +745,29 @@ |
727 | 746 | if ( isset( $options['GROUP BY'] ) ) { |
728 | 747 | $preLimitTail .= " GROUP BY {$options['GROUP BY']}"; |
729 | 748 | } |
| 749 | + |
730 | 750 | if ( isset( $options['HAVING'] ) ) { |
731 | 751 | $preLimitTail .= " HAVING {$options['HAVING']}"; |
732 | 752 | } |
| 753 | + |
733 | 754 | if ( isset( $options['ORDER BY'] ) ) { |
734 | 755 | $preLimitTail .= " ORDER BY {$options['ORDER BY']}"; |
735 | 756 | } |
736 | 757 | |
737 | | - //if (isset($options['LIMIT'])) { |
| 758 | + // if (isset($options['LIMIT'])) { |
738 | 759 | // $tailOpts .= $this->limitResult('', $options['LIMIT'], |
739 | 760 | // isset($options['OFFSET']) ? $options['OFFSET'] |
740 | 761 | // : false); |
741 | | - //} |
| 762 | + // } |
742 | 763 | |
743 | 764 | if ( isset( $noKeyOptions['FOR UPDATE'] ) ) { |
744 | 765 | $postLimitTail .= ' FOR UPDATE'; |
745 | 766 | } |
| 767 | + |
746 | 768 | if ( isset( $noKeyOptions['LOCK IN SHARE MODE'] ) ) { |
747 | 769 | $postLimitTail .= ' LOCK IN SHARE MODE'; |
748 | 770 | } |
| 771 | + |
749 | 772 | if ( isset( $noKeyOptions['DISTINCT'] ) || isset( $noKeyOptions['DISTINCTROW'] ) ) { |
750 | 773 | $startOpts .= 'DISTINCT'; |
751 | 774 | } |
— | — | @@ -753,24 +776,31 @@ |
754 | 777 | if ( isset( $noKeyOptions['STRAIGHT_JOIN'] ) ) { |
755 | 778 | $startOpts .= ' /*! STRAIGHT_JOIN */'; |
756 | 779 | } |
| 780 | + |
757 | 781 | if ( isset( $noKeyOptions['HIGH_PRIORITY'] ) ) { |
758 | 782 | $startOpts .= ' HIGH_PRIORITY'; |
759 | 783 | } |
| 784 | + |
760 | 785 | if ( isset( $noKeyOptions['SQL_BIG_RESULT'] ) ) { |
761 | 786 | $startOpts .= ' SQL_BIG_RESULT'; |
762 | 787 | } |
| 788 | + |
763 | 789 | if ( isset( $noKeyOptions['SQL_BUFFER_RESULT'] ) ) { |
764 | 790 | $startOpts .= ' SQL_BUFFER_RESULT'; |
765 | 791 | } |
| 792 | + |
766 | 793 | if ( isset( $noKeyOptions['SQL_SMALL_RESULT'] ) ) { |
767 | 794 | $startOpts .= ' SQL_SMALL_RESULT'; |
768 | 795 | } |
| 796 | + |
769 | 797 | if ( isset( $noKeyOptions['SQL_CALC_FOUND_ROWS'] ) ) { |
770 | 798 | $startOpts .= ' SQL_CALC_FOUND_ROWS'; |
771 | 799 | } |
| 800 | + |
772 | 801 | if ( isset( $noKeyOptions['SQL_CACHE'] ) ) { |
773 | 802 | $startOpts .= ' SQL_CACHE'; |
774 | 803 | } |
| 804 | + |
775 | 805 | if ( isset( $noKeyOptions['SQL_NO_CACHE'] ) ) { |
776 | 806 | $startOpts .= ' SQL_NO_CACHE'; |
777 | 807 | } |
— | — | @@ -797,8 +827,9 @@ |
798 | 828 | * (e.g. array( 'page' => array('LEFT JOIN','page_latest=rev_id') ) |
799 | 829 | * @return mixed Database result resource (feed to DatabaseBase::fetchObject or whatever), or false on failure |
800 | 830 | */ |
801 | | - function select( $table, $vars, $conds='', $fname = 'DatabaseBase::select', $options = array(), $join_conds = array() ) { |
| 831 | + function select( $table, $vars, $conds = '', $fname = 'DatabaseBase::select', $options = array(), $join_conds = array() ) { |
802 | 832 | $sql = $this->selectSQLText( $table, $vars, $conds, $fname, $options, $join_conds ); |
| 833 | + |
803 | 834 | return $this->query( $sql, $fname ); |
804 | 835 | } |
805 | 836 | |
— | — | @@ -815,21 +846,23 @@ |
816 | 847 | * (e.g. array( 'page' => array('LEFT JOIN','page_latest=rev_id') ) |
817 | 848 | * @return string, the SQL text |
818 | 849 | */ |
819 | | - function selectSQLText( $table, $vars, $conds='', $fname = 'DatabaseBase::select', $options = array(), $join_conds = array() ) { |
820 | | - if( is_array( $vars ) ) { |
| 850 | + function selectSQLText( $table, $vars, $conds = '', $fname = 'DatabaseBase::select', $options = array(), $join_conds = array() ) { |
| 851 | + if ( is_array( $vars ) ) { |
821 | 852 | $vars = implode( ',', $vars ); |
822 | 853 | } |
823 | | - if( !is_array( $options ) ) { |
| 854 | + |
| 855 | + if ( !is_array( $options ) ) { |
824 | 856 | $options = array( $options ); |
825 | 857 | } |
826 | | - if( is_array( $table ) ) { |
827 | | - if ( !empty($join_conds) || ( isset( $options['USE INDEX'] ) && is_array( @$options['USE INDEX'] ) ) ) { |
| 858 | + |
| 859 | + if ( is_array( $table ) ) { |
| 860 | + if ( !empty( $join_conds ) || ( isset( $options['USE INDEX'] ) && is_array( @$options['USE INDEX'] ) ) ) { |
828 | 861 | $from = ' FROM ' . $this->tableNamesWithUseIndexOrJOIN( $table, @$options['USE INDEX'], $join_conds ); |
829 | 862 | } else { |
830 | 863 | $from = ' FROM ' . implode( ',', array_map( array( &$this, 'tableName' ), $table ) ); |
831 | 864 | } |
832 | | - } elseif ($table!='') { |
833 | | - if ($table{0}==' ') { |
| 865 | + } elseif ( $table != '' ) { |
| 866 | + if ( $table { 0 } == ' ' ) { |
834 | 867 | $from = ' FROM ' . $table; |
835 | 868 | } else { |
836 | 869 | $from = ' FROM ' . $this->tableName( $table ); |
— | — | @@ -840,7 +873,7 @@ |
841 | 874 | |
842 | 875 | list( $startOpts, $useIndex, $preLimitTail, $postLimitTail ) = $this->makeSelectOptions( $options ); |
843 | 876 | |
844 | | - if( !empty( $conds ) ) { |
| 877 | + if ( !empty( $conds ) ) { |
845 | 878 | if ( is_array( $conds ) ) { |
846 | 879 | $conds = $this->makeList( $conds, LIST_AND ); |
847 | 880 | } |
— | — | @@ -849,14 +882,15 @@ |
850 | 883 | $sql = "SELECT $startOpts $vars $from $useIndex $preLimitTail"; |
851 | 884 | } |
852 | 885 | |
853 | | - if (isset($options['LIMIT'])) |
854 | | - $sql = $this->limitResult($sql, $options['LIMIT'], |
855 | | - isset($options['OFFSET']) ? $options['OFFSET'] : false); |
| 886 | + if ( isset( $options['LIMIT'] ) ) |
| 887 | + $sql = $this->limitResult( $sql, $options['LIMIT'], |
| 888 | + isset( $options['OFFSET'] ) ? $options['OFFSET'] : false ); |
856 | 889 | $sql = "$sql $postLimitTail"; |
857 | 890 | |
858 | | - if (isset($options['EXPLAIN'])) { |
| 891 | + if ( isset( $options['EXPLAIN'] ) ) { |
859 | 892 | $sql = 'EXPLAIN ' . $sql; |
860 | 893 | } |
| 894 | + |
861 | 895 | return $sql; |
862 | 896 | } |
863 | 897 | |
— | — | @@ -881,13 +915,17 @@ |
882 | 916 | function selectRow( $table, $vars, $conds, $fname = 'DatabaseBase::selectRow', $options = array(), $join_conds = array() ) { |
883 | 917 | $options['LIMIT'] = 1; |
884 | 918 | $res = $this->select( $table, $vars, $conds, $fname, $options, $join_conds ); |
| 919 | + |
885 | 920 | if ( $res === false ) { |
886 | 921 | return false; |
887 | 922 | } |
888 | | - if ( !$this->numRows($res) ) { |
| 923 | + |
| 924 | + if ( !$this->numRows( $res ) ) { |
889 | 925 | return false; |
890 | 926 | } |
| 927 | + |
891 | 928 | $obj = $this->fetchObject( $res ); |
| 929 | + |
892 | 930 | return $obj; |
893 | 931 | } |
894 | 932 | |
— | — | @@ -904,13 +942,15 @@ |
905 | 943 | * @param $options Array: options for select |
906 | 944 | * @return Integer: row count |
907 | 945 | */ |
908 | | - public function estimateRowCount( $table, $vars='*', $conds='', $fname = 'DatabaseBase::estimateRowCount', $options = array() ) { |
| 946 | + public function estimateRowCount( $table, $vars = '*', $conds = '', $fname = 'DatabaseBase::estimateRowCount', $options = array() ) { |
909 | 947 | $rows = 0; |
910 | 948 | $res = $this->select ( $table, 'COUNT(*) AS rowcount', $conds, $fname, $options ); |
| 949 | + |
911 | 950 | if ( $res ) { |
912 | 951 | $row = $this->fetchRow( $res ); |
913 | 952 | $rows = ( isset( $row['rowcount'] ) ) ? $row['rowcount'] : 0; |
914 | 953 | } |
| 954 | + |
915 | 955 | return $rows; |
916 | 956 | } |
917 | 957 | |
— | — | @@ -925,17 +965,17 @@ |
926 | 966 | # as to avoid crashing php on some large strings. |
927 | 967 | # $sql = preg_replace ( "/'([^\\\\']|\\\\.)*'|\"([^\\\\\"]|\\\\.)*\"/", "'X'", $sql); |
928 | 968 | |
929 | | - $sql = str_replace ( "\\\\", '', $sql); |
930 | | - $sql = str_replace ( "\\'", '', $sql); |
931 | | - $sql = str_replace ( "\\\"", '', $sql); |
932 | | - $sql = preg_replace ("/'.*'/s", "'X'", $sql); |
933 | | - $sql = preg_replace ('/".*"/s', "'X'", $sql); |
| 969 | + $sql = str_replace ( "\\\\", '', $sql ); |
| 970 | + $sql = str_replace ( "\\'", '', $sql ); |
| 971 | + $sql = str_replace ( "\\\"", '', $sql ); |
| 972 | + $sql = preg_replace ( "/'.*'/s", "'X'", $sql ); |
| 973 | + $sql = preg_replace ( '/".*"/s', "'X'", $sql ); |
934 | 974 | |
935 | 975 | # All newlines, tabs, etc replaced by single space |
936 | | - $sql = preg_replace ( '/\s+/', ' ', $sql); |
| 976 | + $sql = preg_replace ( '/\s+/', ' ', $sql ); |
937 | 977 | |
938 | 978 | # All numbers => N |
939 | | - $sql = preg_replace ('/-?[0-9]+/s', 'N', $sql); |
| 979 | + $sql = preg_replace ( '/-?[0-9]+/s', 'N', $sql ); |
940 | 980 | |
941 | 981 | return $sql; |
942 | 982 | } |
— | — | @@ -950,6 +990,7 @@ |
951 | 991 | */ |
952 | 992 | function fieldExists( $table, $field, $fname = 'DatabaseBase::fieldExists' ) { |
953 | 993 | $info = $this->fieldInfo( $table, $field ); |
| 994 | + |
954 | 995 | return (bool)$info; |
955 | 996 | } |
956 | 997 | |
— | — | @@ -978,20 +1019,22 @@ |
979 | 1020 | # http://dev.mysql.com/doc/mysql/en/SHOW_INDEX.html |
980 | 1021 | $table = $this->tableName( $table ); |
981 | 1022 | $index = $this->indexName( $index ); |
982 | | - $sql = 'SHOW INDEX FROM '.$table; |
| 1023 | + $sql = 'SHOW INDEX FROM ' . $table; |
983 | 1024 | $res = $this->query( $sql, $fname ); |
| 1025 | + |
984 | 1026 | if ( !$res ) { |
985 | 1027 | return null; |
986 | 1028 | } |
987 | 1029 | |
988 | 1030 | $result = array(); |
| 1031 | + |
989 | 1032 | while ( $row = $this->fetchObject( $res ) ) { |
990 | 1033 | if ( $row->Key_name == $index ) { |
991 | 1034 | $result[] = $row; |
992 | 1035 | } |
993 | 1036 | } |
994 | 1037 | |
995 | | - return empty($result) ? false : $result; |
| 1038 | + return empty( $result ) ? false : $result; |
996 | 1039 | } |
997 | 1040 | |
998 | 1041 | /** |
— | — | @@ -1002,6 +1045,7 @@ |
1003 | 1046 | $old = $this->ignoreErrors( true ); |
1004 | 1047 | $res = $this->query( "SELECT 1 FROM $table LIMIT 1" ); |
1005 | 1048 | $this->ignoreErrors( $old ); |
| 1049 | + |
1006 | 1050 | return (bool)$res; |
1007 | 1051 | } |
1008 | 1052 | |
— | — | @@ -1012,6 +1056,7 @@ |
1013 | 1057 | if ( $res instanceof ResultWrapper ) { |
1014 | 1058 | $res = $res->result; |
1015 | 1059 | } |
| 1060 | + |
1016 | 1061 | return mysql_field_type( $res, $index ); |
1017 | 1062 | } |
1018 | 1063 | |
— | — | @@ -1020,12 +1065,14 @@ |
1021 | 1066 | */ |
1022 | 1067 | function indexUnique( $table, $index ) { |
1023 | 1068 | $indexInfo = $this->indexInfo( $table, $index ); |
| 1069 | + |
1024 | 1070 | if ( !$indexInfo ) { |
1025 | 1071 | return null; |
1026 | 1072 | } |
| 1073 | + |
1027 | 1074 | return !$indexInfo[0]->Non_unique; |
1028 | 1075 | } |
1029 | | - |
| 1076 | + |
1030 | 1077 | /** |
1031 | 1078 | * INSERT wrapper, inserts an array into a table |
1032 | 1079 | * |
— | — | @@ -1049,9 +1096,11 @@ |
1050 | 1097 | } |
1051 | 1098 | |
1052 | 1099 | $table = $this->tableName( $table ); |
| 1100 | + |
1053 | 1101 | if ( !is_array( $options ) ) { |
1054 | 1102 | $options = array( $options ); |
1055 | 1103 | } |
| 1104 | + |
1056 | 1105 | if ( isset( $a[0] ) && is_array( $a[0] ) ) { |
1057 | 1106 | $multi = true; |
1058 | 1107 | $keys = array_keys( $a[0] ); |
— | — | @@ -1088,17 +1137,21 @@ |
1089 | 1138 | * @return string |
1090 | 1139 | */ |
1091 | 1140 | function makeUpdateOptions( $options ) { |
1092 | | - if( !is_array( $options ) ) { |
| 1141 | + if ( !is_array( $options ) ) { |
1093 | 1142 | $options = array( $options ); |
1094 | 1143 | } |
| 1144 | + |
1095 | 1145 | $opts = array(); |
| 1146 | + |
1096 | 1147 | if ( in_array( 'LOW_PRIORITY', $options ) ) { |
1097 | 1148 | $opts[] = $this->lowPriorityOption(); |
1098 | 1149 | } |
| 1150 | + |
1099 | 1151 | if ( in_array( 'IGNORE', $options ) ) { |
1100 | 1152 | $opts[] = 'IGNORE'; |
1101 | 1153 | } |
1102 | | - return implode(' ', $opts); |
| 1154 | + |
| 1155 | + return implode( ' ', $opts ); |
1103 | 1156 | } |
1104 | 1157 | |
1105 | 1158 | /** |
— | — | @@ -1117,9 +1170,11 @@ |
1118 | 1171 | $table = $this->tableName( $table ); |
1119 | 1172 | $opts = $this->makeUpdateOptions( $options ); |
1120 | 1173 | $sql = "UPDATE $opts $table SET " . $this->makeList( $values, LIST_SET ); |
| 1174 | + |
1121 | 1175 | if ( $conds != '*' ) { |
1122 | 1176 | $sql .= " WHERE " . $this->makeList( $conds, LIST_AND ); |
1123 | 1177 | } |
| 1178 | + |
1124 | 1179 | return $this->query( $sql, $fname ); |
1125 | 1180 | } |
1126 | 1181 | |
— | — | @@ -1139,11 +1194,12 @@ |
1140 | 1195 | |
1141 | 1196 | $first = true; |
1142 | 1197 | $list = ''; |
| 1198 | + |
1143 | 1199 | foreach ( $a as $field => $value ) { |
1144 | 1200 | if ( !$first ) { |
1145 | 1201 | if ( $mode == LIST_AND ) { |
1146 | 1202 | $list .= ' AND '; |
1147 | | - } elseif($mode == LIST_OR) { |
| 1203 | + } elseif ( $mode == LIST_OR ) { |
1148 | 1204 | $list .= ' OR '; |
1149 | 1205 | } else { |
1150 | 1206 | $list .= ','; |
— | — | @@ -1151,21 +1207,22 @@ |
1152 | 1208 | } else { |
1153 | 1209 | $first = false; |
1154 | 1210 | } |
1155 | | - if ( ($mode == LIST_AND || $mode == LIST_OR) && is_numeric( $field ) ) { |
| 1211 | + |
| 1212 | + if ( ( $mode == LIST_AND || $mode == LIST_OR ) && is_numeric( $field ) ) { |
1156 | 1213 | $list .= "($value)"; |
1157 | | - } elseif ( ($mode == LIST_SET) && is_numeric( $field ) ) { |
| 1214 | + } elseif ( ( $mode == LIST_SET ) && is_numeric( $field ) ) { |
1158 | 1215 | $list .= "$value"; |
1159 | | - } elseif ( ($mode == LIST_AND || $mode == LIST_OR) && is_array($value) ) { |
| 1216 | + } elseif ( ( $mode == LIST_AND || $mode == LIST_OR ) && is_array( $value ) ) { |
1160 | 1217 | if ( count( $value ) == 0 ) { |
1161 | | - throw new MWException( __METHOD__.': empty input' ); |
1162 | | - } elseif( count( $value ) == 1 ) { |
| 1218 | + throw new MWException( __METHOD__ . ': empty input' ); |
| 1219 | + } elseif ( count( $value ) == 1 ) { |
1163 | 1220 | // Special-case single values, as IN isn't terribly efficient |
1164 | 1221 | // Don't necessarily assume the single key is 0; we don't |
1165 | 1222 | // enforce linear numeric ordering on other arrays here. |
1166 | 1223 | $value = array_values( $value ); |
1167 | | - $list .= $field." = ".$this->addQuotes( $value[0] ); |
| 1224 | + $list .= $field . " = " . $this->addQuotes( $value[0] ); |
1168 | 1225 | } else { |
1169 | | - $list .= $field." IN (".$this->makeList($value).") "; |
| 1226 | + $list .= $field . " IN (" . $this->makeList( $value ) . ") "; |
1170 | 1227 | } |
1171 | 1228 | } elseif ( $value === null ) { |
1172 | 1229 | if ( $mode == LIST_AND || $mode == LIST_OR ) { |
— | — | @@ -1181,6 +1238,7 @@ |
1182 | 1239 | $list .= $mode == LIST_NAMES ? $value : $this->addQuotes( $value ); |
1183 | 1240 | } |
1184 | 1241 | } |
| 1242 | + |
1185 | 1243 | return $list; |
1186 | 1244 | } |
1187 | 1245 | |
— | — | @@ -1195,11 +1253,12 @@ |
1196 | 1254 | */ |
1197 | 1255 | function makeWhereFrom2d( $data, $baseKey, $subKey ) { |
1198 | 1256 | $conds = array(); |
| 1257 | + |
1199 | 1258 | foreach ( $data as $base => $sub ) { |
1200 | 1259 | if ( count( $sub ) ) { |
1201 | 1260 | $conds[] = $this->makeList( |
1202 | 1261 | array( $baseKey => $base, $subKey => array_keys( $sub ) ), |
1203 | | - LIST_AND); |
| 1262 | + LIST_AND ); |
1204 | 1263 | } |
1205 | 1264 | } |
1206 | 1265 | |
— | — | @@ -1215,28 +1274,28 @@ |
1216 | 1275 | * Bitwise operations |
1217 | 1276 | */ |
1218 | 1277 | |
1219 | | - function bitNot($field) { |
| 1278 | + function bitNot( $field ) { |
1220 | 1279 | return "(~$field)"; |
1221 | 1280 | } |
1222 | 1281 | |
1223 | | - function bitAnd($fieldLeft, $fieldRight) { |
| 1282 | + function bitAnd( $fieldLeft, $fieldRight ) { |
1224 | 1283 | return "($fieldLeft & $fieldRight)"; |
1225 | 1284 | } |
1226 | 1285 | |
1227 | | - function bitOr($fieldLeft, $fieldRight) { |
| 1286 | + function bitOr( $fieldLeft, $fieldRight ) { |
1228 | 1287 | return "($fieldLeft | $fieldRight)"; |
1229 | 1288 | } |
1230 | 1289 | |
1231 | 1290 | /** |
1232 | 1291 | * Change the current database |
1233 | 1292 | * |
| 1293 | + * @todo Explain what exactly will fail if this is not overridden. |
1234 | 1294 | * @return bool Success or failure |
1235 | 1295 | */ |
1236 | 1296 | function selectDB( $db ) { |
1237 | 1297 | # Stub. Shouldn't cause serious problems if it's not overridden, but |
1238 | 1298 | # if your database engine supports a concept similar to MySQL's |
1239 | | - # databases you may as well. TODO: explain what exactly will fail if |
1240 | | - # this is not overridden. |
| 1299 | + # databases you may as well. |
1241 | 1300 | return true; |
1242 | 1301 | } |
1243 | 1302 | |
— | — | @@ -1284,7 +1343,7 @@ |
1285 | 1344 | # Note that we use a whitespace test rather than a \b test to avoid |
1286 | 1345 | # any remote case where a word like on may be inside of a table name |
1287 | 1346 | # surrounded by symbols which may be considered word breaks. |
1288 | | - if( preg_match( '/(^|\s)(DISTINCT|JOIN|ON|AS)(\s|$)/i', $name ) !== 0 ) { |
| 1347 | + if ( preg_match( '/(^|\s)(DISTINCT|JOIN|ON|AS)(\s|$)/i', $name ) !== 0 ) { |
1289 | 1348 | return $name; |
1290 | 1349 | } |
1291 | 1350 | |
— | — | @@ -1292,7 +1351,7 @@ |
1293 | 1352 | # We reverse the explode so that database.table and table both output |
1294 | 1353 | # the correct table. |
1295 | 1354 | $dbDetails = array_reverse( explode( '.', $name, 2 ) ); |
1296 | | - if( isset( $dbDetails[1] ) ) { |
| 1355 | + if ( isset( $dbDetails[1] ) ) { |
1297 | 1356 | @list( $table, $database ) = $dbDetails; |
1298 | 1357 | } else { |
1299 | 1358 | @list( $table ) = $dbDetails; |
— | — | @@ -1301,13 +1360,13 @@ |
1302 | 1361 | |
1303 | 1362 | # A database name has been specified in input. Quote the table name |
1304 | 1363 | # because we don't want any prefixes added. |
1305 | | - if( isset($database) ) { |
| 1364 | + if ( isset( $database ) ) { |
1306 | 1365 | $table = ( $table[0] == '`' ? $table : "`{$table}`" ); |
1307 | 1366 | } |
1308 | 1367 | |
1309 | 1368 | # Note that we use the long format because php will complain in in_array if |
1310 | 1369 | # the input is not an array, and will complain in is_array if it is not set. |
1311 | | - if( !isset( $database ) # Don't use shared database if pre selected. |
| 1370 | + if ( !isset( $database ) # Don't use shared database if pre selected. |
1312 | 1371 | && isset( $wgSharedDB ) # We have a shared database |
1313 | 1372 | && $table[0] != '`' # Paranoia check to prevent shared tables listing '`table`' |
1314 | 1373 | && isset( $wgSharedTables ) |
— | — | @@ -1318,15 +1377,14 @@ |
1319 | 1378 | } |
1320 | 1379 | |
1321 | 1380 | # Quote the $database and $table and apply the prefix if not quoted. |
1322 | | - if( isset($database) ) { |
| 1381 | + if ( isset( $database ) ) { |
1323 | 1382 | $database = ( $database[0] == '`' ? $database : "`{$database}`" ); |
1324 | 1383 | } |
1325 | 1384 | $table = ( $table[0] == '`' ? $table : "`{$prefix}{$table}`" ); |
1326 | 1385 | |
1327 | 1386 | # Merge our database and table into our final table name. |
1328 | | - $tableName = ( isset($database) ? "{$database}.{$table}" : "{$table}" ); |
| 1387 | + $tableName = ( isset( $database ) ? "{$database}.{$table}" : "{$table}" ); |
1329 | 1388 | |
1330 | | - # We're finished, return. |
1331 | 1389 | return $tableName; |
1332 | 1390 | } |
1333 | 1391 | |
— | — | @@ -1342,9 +1400,11 @@ |
1343 | 1401 | public function tableNames() { |
1344 | 1402 | $inArray = func_get_args(); |
1345 | 1403 | $retVal = array(); |
| 1404 | + |
1346 | 1405 | foreach ( $inArray as $name ) { |
1347 | 1406 | $retVal[$name] = $this->tableName( $name ); |
1348 | 1407 | } |
| 1408 | + |
1349 | 1409 | return $retVal; |
1350 | 1410 | } |
1351 | 1411 | |
— | — | @@ -1360,9 +1420,11 @@ |
1361 | 1421 | public function tableNamesN() { |
1362 | 1422 | $inArray = func_get_args(); |
1363 | 1423 | $retVal = array(); |
| 1424 | + |
1364 | 1425 | foreach ( $inArray as $name ) { |
1365 | 1426 | $retVal[] = $this->tableName( $name ); |
1366 | 1427 | } |
| 1428 | + |
1367 | 1429 | return $retVal; |
1368 | 1430 | } |
1369 | 1431 | |
— | — | @@ -1372,41 +1434,48 @@ |
1373 | 1435 | function tableNamesWithUseIndexOrJOIN( $tables, $use_index = array(), $join_conds = array() ) { |
1374 | 1436 | $ret = array(); |
1375 | 1437 | $retJOIN = array(); |
1376 | | - $use_index_safe = is_array($use_index) ? $use_index : array(); |
1377 | | - $join_conds_safe = is_array($join_conds) ? $join_conds : array(); |
| 1438 | + $use_index_safe = is_array( $use_index ) ? $use_index : array(); |
| 1439 | + $join_conds_safe = is_array( $join_conds ) ? $join_conds : array(); |
| 1440 | + |
1378 | 1441 | foreach ( $tables as $table ) { |
1379 | 1442 | // Is there a JOIN and INDEX clause for this table? |
1380 | | - if ( isset($join_conds_safe[$table]) && isset($use_index_safe[$table]) ) { |
| 1443 | + if ( isset( $join_conds_safe[$table] ) && isset( $use_index_safe[$table] ) ) { |
1381 | 1444 | $tableClause = $join_conds_safe[$table][0] . ' ' . $this->tableName( $table ); |
1382 | 1445 | $tableClause .= ' ' . $this->useIndexClause( implode( ',', (array)$use_index_safe[$table] ) ); |
1383 | | - $on = $this->makeList((array)$join_conds_safe[$table][1], LIST_AND); |
| 1446 | + $on = $this->makeList( (array)$join_conds_safe[$table][1], LIST_AND ); |
| 1447 | + |
1384 | 1448 | if ( $on != '' ) { |
1385 | 1449 | $tableClause .= ' ON (' . $on . ')'; |
1386 | 1450 | } |
| 1451 | + |
1387 | 1452 | $retJOIN[] = $tableClause; |
1388 | 1453 | // Is there an INDEX clause? |
1389 | | - } else if ( isset($use_index_safe[$table]) ) { |
| 1454 | + } else if ( isset( $use_index_safe[$table] ) ) { |
1390 | 1455 | $tableClause = $this->tableName( $table ); |
1391 | 1456 | $tableClause .= ' ' . $this->useIndexClause( implode( ',', (array)$use_index_safe[$table] ) ); |
1392 | 1457 | $ret[] = $tableClause; |
1393 | 1458 | // Is there a JOIN clause? |
1394 | | - } else if ( isset($join_conds_safe[$table]) ) { |
| 1459 | + } else if ( isset( $join_conds_safe[$table] ) ) { |
1395 | 1460 | $tableClause = $join_conds_safe[$table][0] . ' ' . $this->tableName( $table ); |
1396 | | - $on = $this->makeList((array)$join_conds_safe[$table][1], LIST_AND); |
| 1461 | + $on = $this->makeList( (array)$join_conds_safe[$table][1], LIST_AND ); |
| 1462 | + |
1397 | 1463 | if ( $on != '' ) { |
1398 | 1464 | $tableClause .= ' ON (' . $on . ')'; |
1399 | 1465 | } |
| 1466 | + |
1400 | 1467 | $retJOIN[] = $tableClause; |
1401 | 1468 | } else { |
1402 | 1469 | $tableClause = $this->tableName( $table ); |
1403 | 1470 | $ret[] = $tableClause; |
1404 | 1471 | } |
1405 | 1472 | } |
| 1473 | + |
1406 | 1474 | // We can't separate explicit JOIN clauses with ',', use ' ' for those |
1407 | | - $straightJoins = !empty($ret) ? implode( ',', $ret ) : ""; |
1408 | | - $otherJoins = !empty($retJOIN) ? implode( ' ', $retJOIN ) : ""; |
| 1475 | + $straightJoins = !empty( $ret ) ? implode( ',', $ret ) : ""; |
| 1476 | + $otherJoins = !empty( $retJOIN ) ? implode( ' ', $retJOIN ) : ""; |
| 1477 | + |
1409 | 1478 | // Compile our final table clause |
1410 | | - return implode(' ',array($straightJoins,$otherJoins) ); |
| 1479 | + return implode( ' ', array( $straightJoins, $otherJoins ) ); |
1411 | 1480 | } |
1412 | 1481 | |
1413 | 1482 | /** |
— | — | @@ -1419,6 +1488,7 @@ |
1420 | 1489 | 'un_user_id' => 'user_id', |
1421 | 1490 | 'un_user_ip' => 'user_ip', |
1422 | 1491 | ); |
| 1492 | + |
1423 | 1493 | if ( isset( $renamed[$index] ) ) { |
1424 | 1494 | return $renamed[$index]; |
1425 | 1495 | } else { |
— | — | @@ -1457,6 +1527,7 @@ |
1458 | 1528 | $s = str_replace( '\\', '\\\\', $s ); |
1459 | 1529 | $s = $this->strencode( $s ); |
1460 | 1530 | $s = str_replace( array( '%', '_' ), array( '\%', '\_' ), $s ); |
| 1531 | + |
1461 | 1532 | return $s; |
1462 | 1533 | } |
1463 | 1534 | |
— | — | @@ -1474,18 +1545,21 @@ |
1475 | 1546 | */ |
1476 | 1547 | function buildLike() { |
1477 | 1548 | $params = func_get_args(); |
1478 | | - if (count($params) > 0 && is_array($params[0])) { |
| 1549 | + |
| 1550 | + if ( count( $params ) > 0 && is_array( $params[0] ) ) { |
1479 | 1551 | $params = $params[0]; |
1480 | 1552 | } |
1481 | 1553 | |
1482 | 1554 | $s = ''; |
1483 | | - foreach( $params as $value) { |
1484 | | - if( $value instanceof LikeMatch ) { |
| 1555 | + |
| 1556 | + foreach ( $params as $value ) { |
| 1557 | + if ( $value instanceof LikeMatch ) { |
1485 | 1558 | $s .= $value->toString(); |
1486 | 1559 | } else { |
1487 | 1560 | $s .= $this->escapeLikeInternal( $value ); |
1488 | 1561 | } |
1489 | 1562 | } |
| 1563 | + |
1490 | 1564 | return " LIKE '" . $s . "' "; |
1491 | 1565 | } |
1492 | 1566 | |
— | — | @@ -1548,16 +1622,19 @@ |
1549 | 1623 | $rows = array( $rows ); |
1550 | 1624 | } |
1551 | 1625 | |
1552 | | - $sql = "REPLACE INTO $table (" . implode( ',', array_keys( $rows[0] ) ) .') VALUES '; |
| 1626 | + $sql = "REPLACE INTO $table (" . implode( ',', array_keys( $rows[0] ) ) . ') VALUES '; |
1553 | 1627 | $first = true; |
| 1628 | + |
1554 | 1629 | foreach ( $rows as $row ) { |
1555 | 1630 | if ( $first ) { |
1556 | 1631 | $first = false; |
1557 | 1632 | } else { |
1558 | 1633 | $sql .= ','; |
1559 | 1634 | } |
| 1635 | + |
1560 | 1636 | $sql .= '(' . $this->makeList( $row ) . ')'; |
1561 | 1637 | } |
| 1638 | + |
1562 | 1639 | return $this->query( $sql, $fname ); |
1563 | 1640 | } |
1564 | 1641 | |
— | — | @@ -1585,6 +1662,7 @@ |
1586 | 1663 | $delTable = $this->tableName( $delTable ); |
1587 | 1664 | $joinTable = $this->tableName( $joinTable ); |
1588 | 1665 | $sql = "DELETE $delTable FROM $delTable, $joinTable WHERE $delVar=$joinVar "; |
| 1666 | + |
1589 | 1667 | if ( $conds != '*' ) { |
1590 | 1668 | $sql .= ' AND ' . $this->makeList( $conds, LIST_AND ); |
1591 | 1669 | } |
— | — | @@ -1602,11 +1680,13 @@ |
1603 | 1681 | $row = $this->fetchObject( $res ); |
1604 | 1682 | |
1605 | 1683 | $m = array(); |
| 1684 | + |
1606 | 1685 | if ( preg_match( '/\((.*)\)/', $row->Type, $m ) ) { |
1607 | 1686 | $size = $m[1]; |
1608 | 1687 | } else { |
1609 | 1688 | $size = -1; |
1610 | 1689 | } |
| 1690 | + |
1611 | 1691 | return $size; |
1612 | 1692 | } |
1613 | 1693 | |
— | — | @@ -1630,11 +1710,14 @@ |
1631 | 1711 | if ( !$conds ) { |
1632 | 1712 | throw new DBUnexpectedError( $this, 'DatabaseBase::delete() called with no conditions' ); |
1633 | 1713 | } |
| 1714 | + |
1634 | 1715 | $table = $this->tableName( $table ); |
1635 | 1716 | $sql = "DELETE FROM $table"; |
| 1717 | + |
1636 | 1718 | if ( $conds != '*' ) { |
1637 | 1719 | $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND ); |
1638 | 1720 | } |
| 1721 | + |
1639 | 1722 | return $this->query( $sql, $fname ); |
1640 | 1723 | } |
1641 | 1724 | |
— | — | @@ -1649,25 +1732,33 @@ |
1650 | 1733 | $insertOptions = array(), $selectOptions = array() ) |
1651 | 1734 | { |
1652 | 1735 | $destTable = $this->tableName( $destTable ); |
| 1736 | + |
1653 | 1737 | if ( is_array( $insertOptions ) ) { |
1654 | 1738 | $insertOptions = implode( ' ', $insertOptions ); |
1655 | 1739 | } |
1656 | | - if( !is_array( $selectOptions ) ) { |
| 1740 | + |
| 1741 | + if ( !is_array( $selectOptions ) ) { |
1657 | 1742 | $selectOptions = array( $selectOptions ); |
1658 | 1743 | } |
| 1744 | + |
1659 | 1745 | list( $startOpts, $useIndex, $tailOpts ) = $this->makeSelectOptions( $selectOptions ); |
| 1746 | + |
1660 | 1747 | if ( is_array( $srcTable ) ) { |
1661 | 1748 | $srcTable = implode( ',', array_map( array( &$this, 'tableName' ), $srcTable ) ); |
1662 | 1749 | } else { |
1663 | 1750 | $srcTable = $this->tableName( $srcTable ); |
1664 | 1751 | } |
| 1752 | + |
1665 | 1753 | $sql = "INSERT $insertOptions INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ')' . |
1666 | 1754 | " SELECT $startOpts " . implode( ',', $varMap ) . |
1667 | 1755 | " FROM $srcTable $useIndex "; |
| 1756 | + |
1668 | 1757 | if ( $conds != '*' ) { |
1669 | 1758 | $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND ); |
1670 | 1759 | } |
| 1760 | + |
1671 | 1761 | $sql .= " $tailOpts"; |
| 1762 | + |
1672 | 1763 | return $this->query( $sql, $fname ); |
1673 | 1764 | } |
1674 | 1765 | |
— | — | @@ -1689,14 +1780,16 @@ |
1690 | 1781 | * @param $limit Integer: the SQL limit |
1691 | 1782 | * @param $offset Integer the SQL offset (default false) |
1692 | 1783 | */ |
1693 | | - function limitResult( $sql, $limit, $offset=false ) { |
1694 | | - if( !is_numeric( $limit ) ) { |
| 1784 | + function limitResult( $sql, $limit, $offset = false ) { |
| 1785 | + if ( !is_numeric( $limit ) ) { |
1695 | 1786 | throw new DBUnexpectedError( $this, "Invalid non-numeric limit passed to limitResult()\n" ); |
1696 | 1787 | } |
| 1788 | + |
1697 | 1789 | return "$sql LIMIT " |
1698 | | - . ( (is_numeric($offset) && $offset != 0) ? "{$offset}," : "" ) |
| 1790 | + . ( ( is_numeric( $offset ) && $offset != 0 ) ? "{$offset}," : "" ) |
1699 | 1791 | . "{$limit} "; |
1700 | 1792 | } |
| 1793 | + |
1701 | 1794 | function limitResultForUpdate( $sql, $num ) { |
1702 | 1795 | return $this->limitResult( $sql, $num, 0 ); |
1703 | 1796 | } |
— | — | @@ -1718,9 +1811,9 @@ |
1719 | 1812 | * @param $all Boolean: use UNION ALL |
1720 | 1813 | * @return String: SQL fragment |
1721 | 1814 | */ |
1722 | | - function unionQueries($sqls, $all) { |
| 1815 | + function unionQueries( $sqls, $all ) { |
1723 | 1816 | $glue = $all ? ') UNION ALL (' : ') UNION ('; |
1724 | | - return '('.implode( $glue, $sqls ) . ')'; |
| 1817 | + return '(' . implode( $glue, $sqls ) . ')'; |
1725 | 1818 | } |
1726 | 1819 | |
1727 | 1820 | /** |
— | — | @@ -1797,11 +1890,13 @@ |
1798 | 1891 | $function = array_shift( $args ); |
1799 | 1892 | $oldIgnore = $this->ignoreErrors( true ); |
1800 | 1893 | $tries = DEADLOCK_TRIES; |
| 1894 | + |
1801 | 1895 | if ( is_array( $function ) ) { |
1802 | 1896 | $fname = $function[0]; |
1803 | 1897 | } else { |
1804 | 1898 | $fname = $function; |
1805 | 1899 | } |
| 1900 | + |
1806 | 1901 | do { |
1807 | 1902 | $retVal = call_user_func_array( $function, $args ); |
1808 | 1903 | $error = $this->lastError(); |
— | — | @@ -1817,7 +1912,9 @@ |
1818 | 1913 | } |
1819 | 1914 | } |
1820 | 1915 | } while ( $this->wasDeadlock() && --$tries > 0 ); |
| 1916 | + |
1821 | 1917 | $this->ignoreErrors( $oldIgnore ); |
| 1918 | + |
1822 | 1919 | if ( $tries <= 0 ) { |
1823 | 1920 | $this->rollback( $myFname ); |
1824 | 1921 | $this->reportQueryError( $error, $errno, $sql, $fname ); |
— | — | @@ -1844,7 +1941,8 @@ |
1845 | 1942 | } |
1846 | 1943 | |
1847 | 1944 | if ( !is_null( $this->mFakeSlaveLag ) ) { |
1848 | | - $wait = intval( ( $pos->pos - microtime(true) + $this->mFakeSlaveLag ) * 1e6 ); |
| 1945 | + $wait = intval( ( $pos->pos - microtime( true ) + $this->mFakeSlaveLag ) * 1e6 ); |
| 1946 | + |
1849 | 1947 | if ( $wait > $timeout * 1e6 ) { |
1850 | 1948 | wfDebug( "Fake slave timed out waiting for $pos ($wait us)\n" ); |
1851 | 1949 | wfProfileOut( $fname ); |
— | — | @@ -1866,6 +1964,7 @@ |
1867 | 1965 | $encPos = intval( $pos->pos ); |
1868 | 1966 | $sql = "SELECT MASTER_POS_WAIT($encFile, $encPos, $timeout)"; |
1869 | 1967 | $res = $this->doQuery( $sql ); |
| 1968 | + |
1870 | 1969 | if ( $res && $row = $this->fetchRow( $res ) ) { |
1871 | 1970 | wfProfileOut( $fname ); |
1872 | 1971 | return $row[0]; |
— | — | @@ -1880,14 +1979,16 @@ |
1881 | 1980 | */ |
1882 | 1981 | function getSlavePos() { |
1883 | 1982 | if ( !is_null( $this->mFakeSlaveLag ) ) { |
1884 | | - $pos = new MySQLMasterPos( 'fake', microtime(true) - $this->mFakeSlaveLag ); |
1885 | | - wfDebug( __METHOD__.": fake slave pos = $pos\n" ); |
| 1983 | + $pos = new MySQLMasterPos( 'fake', microtime( true ) - $this->mFakeSlaveLag ); |
| 1984 | + wfDebug( __METHOD__ . ": fake slave pos = $pos\n" ); |
1886 | 1985 | return $pos; |
1887 | 1986 | } |
| 1987 | + |
1888 | 1988 | $res = $this->query( 'SHOW SLAVE STATUS', 'DatabaseBase::getSlavePos' ); |
1889 | 1989 | $row = $this->fetchObject( $res ); |
| 1990 | + |
1890 | 1991 | if ( $row ) { |
1891 | | - $pos = isset($row->Exec_master_log_pos) ? $row->Exec_master_log_pos : $row->Exec_Master_Log_Pos; |
| 1992 | + $pos = isset( $row->Exec_master_log_pos ) ? $row->Exec_master_log_pos : $row->Exec_Master_Log_Pos; |
1892 | 1993 | return new MySQLMasterPos( $row->Relay_Master_Log_File, $pos ); |
1893 | 1994 | } else { |
1894 | 1995 | return false; |
— | — | @@ -1901,8 +2002,10 @@ |
1902 | 2003 | if ( $this->mFakeMaster ) { |
1903 | 2004 | return new MySQLMasterPos( 'fake', microtime( true ) ); |
1904 | 2005 | } |
| 2006 | + |
1905 | 2007 | $res = $this->query( 'SHOW MASTER STATUS', 'DatabaseBase::getMasterPos' ); |
1906 | 2008 | $row = $this->fetchObject( $res ); |
| 2009 | + |
1907 | 2010 | if ( $row ) { |
1908 | 2011 | return new MySQLMasterPos( $row->File, $row->Position ); |
1909 | 2012 | } else { |
— | — | @@ -1922,7 +2025,7 @@ |
1923 | 2026 | * End a transaction |
1924 | 2027 | */ |
1925 | 2028 | function commit( $fname = 'DatabaseBase::commit' ) { |
1926 | | - if( $this->mTrxLevel ) { |
| 2029 | + if ( $this->mTrxLevel ) { |
1927 | 2030 | $this->query( 'COMMIT', $fname ); |
1928 | 2031 | $this->mTrxLevel = 0; |
1929 | 2032 | } |
— | — | @@ -1933,7 +2036,7 @@ |
1934 | 2037 | * No-op on non-transactional databases. |
1935 | 2038 | */ |
1936 | 2039 | function rollback( $fname = 'DatabaseBase::rollback' ) { |
1937 | | - if( $this->mTrxLevel ) { |
| 2040 | + if ( $this->mTrxLevel ) { |
1938 | 2041 | $this->query( 'ROLLBACK', $fname, true ); |
1939 | 2042 | $this->mTrxLevel = 0; |
1940 | 2043 | } |
— | — | @@ -1976,8 +2079,8 @@ |
1977 | 2080 | /** |
1978 | 2081 | * Return MW-style timestamp used for MySQL schema |
1979 | 2082 | */ |
1980 | | - function timestamp( $ts=0 ) { |
1981 | | - return wfTimestamp(TS_MW,$ts); |
| 2083 | + function timestamp( $ts = 0 ) { |
| 2084 | + return wfTimestamp( TS_MW, $ts ); |
1982 | 2085 | } |
1983 | 2086 | |
1984 | 2087 | /** |
— | — | @@ -2010,7 +2113,7 @@ |
2011 | 2114 | /** |
2012 | 2115 | * Return aggregated value alias |
2013 | 2116 | */ |
2014 | | - function aggregateValue ($valuedata,$valuename='value') { |
| 2117 | + function aggregateValue ( $valuedata, $valuename = 'value' ) { |
2015 | 2118 | return $valuename; |
2016 | 2119 | } |
2017 | 2120 | |
— | — | @@ -2036,12 +2139,14 @@ |
2037 | 2140 | /** |
2038 | 2141 | * Get status information from SHOW STATUS in an associative array |
2039 | 2142 | */ |
2040 | | - function getStatus($which="%") { |
| 2143 | + function getStatus( $which = "%" ) { |
2041 | 2144 | $res = $this->query( "SHOW STATUS LIKE '{$which}'" ); |
2042 | 2145 | $status = array(); |
| 2146 | + |
2043 | 2147 | while ( $row = $this->fetchObject( $res ) ) { |
2044 | 2148 | $status[$row->Variable_name] = $row->Value; |
2045 | 2149 | } |
| 2150 | + |
2046 | 2151 | return $status; |
2047 | 2152 | } |
2048 | 2153 | |
— | — | @@ -2052,11 +2157,11 @@ |
2053 | 2158 | return 0; |
2054 | 2159 | } |
2055 | 2160 | |
2056 | | - function encodeBlob($b) { |
| 2161 | + function encodeBlob( $b ) { |
2057 | 2162 | return $b; |
2058 | 2163 | } |
2059 | 2164 | |
2060 | | - function decodeBlob($b) { |
| 2165 | + function decodeBlob( $b ) { |
2061 | 2166 | return $b; |
2062 | 2167 | } |
2063 | 2168 | |
— | — | @@ -2079,17 +2184,19 @@ |
2080 | 2185 | */ |
2081 | 2186 | function sourceFile( $filename, $lineCallback = false, $resultCallback = false ) { |
2082 | 2187 | $fp = fopen( $filename, 'r' ); |
| 2188 | + |
2083 | 2189 | if ( false === $fp ) { |
2084 | | - if (!defined("MEDIAWIKI_INSTALL")) |
| 2190 | + if ( !defined( "MEDIAWIKI_INSTALL" ) ) |
2085 | 2191 | throw new MWException( "Could not open \"{$filename}\".\n" ); |
2086 | 2192 | else |
2087 | 2193 | return "Could not open \"{$filename}\".\n"; |
2088 | 2194 | } |
| 2195 | + |
2089 | 2196 | try { |
2090 | 2197 | $error = $this->sourceStream( $fp, $lineCallback, $resultCallback ); |
2091 | 2198 | } |
2092 | | - catch( MWException $e ) { |
2093 | | - if ( defined("MEDIAWIKI_INSTALL") ) { |
| 2199 | + catch ( MWException $e ) { |
| 2200 | + if ( defined( "MEDIAWIKI_INSTALL" ) ) { |
2094 | 2201 | $error = $e->getMessage(); |
2095 | 2202 | } else { |
2096 | 2203 | fclose( $fp ); |
— | — | @@ -2098,6 +2205,7 @@ |
2099 | 2206 | } |
2100 | 2207 | |
2101 | 2208 | fclose( $fp ); |
| 2209 | + |
2102 | 2210 | return $error; |
2103 | 2211 | } |
2104 | 2212 | |
— | — | @@ -2111,6 +2219,7 @@ |
2112 | 2220 | */ |
2113 | 2221 | public static function patchPath( $patch ) { |
2114 | 2222 | global $wgDBtype, $IP; |
| 2223 | + |
2115 | 2224 | if ( file_exists( "$IP/maintenance/$wgDBtype/archives/$patch" ) ) { |
2116 | 2225 | return "$IP/maintenance/$wgDBtype/archives/$patch"; |
2117 | 2226 | } else { |
— | — | @@ -2134,19 +2243,21 @@ |
2135 | 2244 | if ( $lineCallback ) { |
2136 | 2245 | call_user_func( $lineCallback ); |
2137 | 2246 | } |
| 2247 | + |
2138 | 2248 | $line = trim( fgets( $fp, 1024 ) ); |
2139 | 2249 | $sl = strlen( $line ) - 1; |
2140 | 2250 | |
2141 | 2251 | if ( $sl < 0 ) { |
2142 | 2252 | continue; |
2143 | 2253 | } |
2144 | | - if ( '-' == $line{0} && '-' == $line{1} ) { |
| 2254 | + |
| 2255 | + if ( '-' == $line { 0 } && '-' == $line { 1 } ) { |
2145 | 2256 | continue; |
2146 | 2257 | } |
2147 | 2258 | |
2148 | | - ## Allow dollar quoting for function declarations |
2149 | | - if (substr($line,0,4) == '$mw$') { |
2150 | | - if ($dollarquote) { |
| 2259 | + # # Allow dollar quoting for function declarations |
| 2260 | + if ( substr( $line, 0, 4 ) == '$mw$' ) { |
| 2261 | + if ( $dollarquote ) { |
2151 | 2262 | $dollarquote = false; |
2152 | 2263 | $done = true; |
2153 | 2264 | } |
— | — | @@ -2154,8 +2265,8 @@ |
2155 | 2266 | $dollarquote = true; |
2156 | 2267 | } |
2157 | 2268 | } |
2158 | | - else if (!$dollarquote) { |
2159 | | - if ( ';' == $line{$sl} && ($sl < 2 || ';' != $line{$sl - 1})) { |
| 2269 | + else if ( !$dollarquote ) { |
| 2270 | + if ( ';' == $line { $sl } && ( $sl < 2 || ';' != $line { $sl - 1 } ) ) { |
2160 | 2271 | $done = true; |
2161 | 2272 | $line = substr( $line, 0, $sl ); |
2162 | 2273 | } |
— | — | @@ -2164,12 +2275,14 @@ |
2165 | 2276 | if ( $cmd != '' ) { |
2166 | 2277 | $cmd .= ' '; |
2167 | 2278 | } |
| 2279 | + |
2168 | 2280 | $cmd .= "$line\n"; |
2169 | 2281 | |
2170 | 2282 | if ( $done ) { |
2171 | | - $cmd = str_replace(';;', ";", $cmd); |
| 2283 | + $cmd = str_replace( ';;', ";", $cmd ); |
2172 | 2284 | $cmd = $this->replaceVars( $cmd ); |
2173 | 2285 | $res = $this->query( $cmd, __METHOD__ ); |
| 2286 | + |
2174 | 2287 | if ( $resultCallback ) { |
2175 | 2288 | call_user_func( $resultCallback, $res, $this ); |
2176 | 2289 | } |
— | — | @@ -2183,10 +2296,10 @@ |
2184 | 2297 | $done = false; |
2185 | 2298 | } |
2186 | 2299 | } |
| 2300 | + |
2187 | 2301 | return true; |
2188 | 2302 | } |
2189 | 2303 | |
2190 | | - |
2191 | 2304 | /** |
2192 | 2305 | * Replace variables in sourced SQL |
2193 | 2306 | */ |
— | — | @@ -2214,6 +2327,7 @@ |
2215 | 2328 | // Index names |
2216 | 2329 | $ins = preg_replace_callback( '!/\*i\*/([a-zA-Z_0-9]*)!', |
2217 | 2330 | array( $this, 'indexNameCallback' ), $ins ); |
| 2331 | + |
2218 | 2332 | return $ins; |
2219 | 2333 | } |
2220 | 2334 | |
— | — | @@ -2314,7 +2428,6 @@ |
2315 | 2429 | } |
2316 | 2430 | } |
2317 | 2431 | |
2318 | | - |
2319 | 2432 | /****************************************************************************** |
2320 | 2433 | * Utility classes |
2321 | 2434 | *****************************************************************************/ |
— | — | @@ -2326,7 +2439,7 @@ |
2327 | 2440 | class DBObject { |
2328 | 2441 | public $mData; |
2329 | 2442 | |
2330 | | - function __construct($data) { |
| 2443 | + function __construct( $data ) { |
2331 | 2444 | $this->mData = $data; |
2332 | 2445 | } |
2333 | 2446 | |
— | — | @@ -2347,9 +2460,11 @@ |
2348 | 2461 | */ |
2349 | 2462 | class Blob { |
2350 | 2463 | private $mData; |
2351 | | - function __construct($data) { |
| 2464 | + |
| 2465 | + function __construct( $data ) { |
2352 | 2466 | $this->mData = $data; |
2353 | 2467 | } |
| 2468 | + |
2354 | 2469 | function fetch() { |
2355 | 2470 | return $this->mData; |
2356 | 2471 | } |
— | — | @@ -2362,7 +2477,8 @@ |
2363 | 2478 | class MySQLField { |
2364 | 2479 | private $name, $tablename, $default, $max_length, $nullable, |
2365 | 2480 | $is_pk, $is_unique, $is_multiple, $is_key, $type; |
2366 | | - function __construct ($info) { |
| 2481 | + |
| 2482 | + function __construct ( $info ) { |
2367 | 2483 | $this->name = $info->name; |
2368 | 2484 | $this->tablename = $info->table; |
2369 | 2485 | $this->default = $info->def; |
— | — | @@ -2371,7 +2487,7 @@ |
2372 | 2488 | $this->is_pk = $info->primary_key; |
2373 | 2489 | $this->is_unique = $info->unique_key; |
2374 | 2490 | $this->is_multiple = $info->multiple_key; |
2375 | | - $this->is_key = ($this->is_pk || $this->is_unique || $this->is_multiple); |
| 2491 | + $this->is_key = ( $this->is_pk || $this->is_unique || $this->is_multiple ); |
2376 | 2492 | $this->type = $info->type; |
2377 | 2493 | } |
2378 | 2494 | |
— | — | @@ -2431,10 +2547,13 @@ |
2432 | 2548 | |
2433 | 2549 | function getText() { |
2434 | 2550 | global $wgShowDBErrorBacktrace; |
| 2551 | + |
2435 | 2552 | $s = $this->getMessage() . "\n"; |
| 2553 | + |
2436 | 2554 | if ( $wgShowDBErrorBacktrace ) { |
2437 | 2555 | $s .= "Backtrace:\n" . $this->getTraceAsString() . "\n"; |
2438 | 2556 | } |
| 2557 | + |
2439 | 2558 | return $s; |
2440 | 2559 | } |
2441 | 2560 | } |
— | — | @@ -2447,10 +2566,13 @@ |
2448 | 2567 | |
2449 | 2568 | function __construct( DatabaseBase &$db, $error = 'unknown error' ) { |
2450 | 2569 | $msg = 'DB connection error'; |
| 2570 | + |
2451 | 2571 | if ( trim( $error ) != '' ) { |
2452 | 2572 | $msg .= ": $error"; |
2453 | 2573 | } |
| 2574 | + |
2454 | 2575 | $this->error = $error; |
| 2576 | + |
2455 | 2577 | parent::__construct( $db, $msg ); |
2456 | 2578 | } |
2457 | 2579 | |
— | — | @@ -2471,7 +2593,9 @@ |
2472 | 2594 | |
2473 | 2595 | function getPageTitle() { |
2474 | 2596 | global $wgSitename, $wgLang; |
| 2597 | + |
2475 | 2598 | $header = "$wgSitename has a problem"; |
| 2599 | + |
2476 | 2600 | if ( $wgLang instanceof Language ) { |
2477 | 2601 | $header = htmlspecialchars( $wgLang->getMessage( 'dberr-header' ) ); |
2478 | 2602 | } |
— | — | @@ -2498,7 +2622,7 @@ |
2499 | 2623 | } |
2500 | 2624 | |
2501 | 2625 | if ( trim( $this->error ) == '' ) { |
2502 | | - $this->error = $this->db->getProperty('mServer'); |
| 2626 | + $this->error = $this->db->getProperty( 'mServer' ); |
2503 | 2627 | } |
2504 | 2628 | |
2505 | 2629 | $noconnect = "<p><strong>$sorry</strong><br />$again</p><p><small>$info</small></p>"; |
— | — | @@ -2510,33 +2634,38 @@ |
2511 | 2635 | |
2512 | 2636 | $extra = $this->searchForm(); |
2513 | 2637 | |
2514 | | - if( $wgUseFileCache ) { |
| 2638 | + if ( $wgUseFileCache ) { |
2515 | 2639 | try { |
2516 | 2640 | $cache = $this->fileCachedPage(); |
2517 | 2641 | # Cached version on file system? |
2518 | | - if( $cache !== null ) { |
| 2642 | + if ( $cache !== null ) { |
2519 | 2643 | # Hack: extend the body for error messages |
2520 | | - $cache = str_replace( array('</html>','</body>'), '', $cache ); |
| 2644 | + $cache = str_replace( array( '</html>', '</body>' ), '', $cache ); |
2521 | 2645 | # Add cache notice... |
2522 | 2646 | $cachederror = "This is a cached copy of the requested page, and may not be up to date. "; |
| 2647 | + |
2523 | 2648 | # Localize it if possible... |
2524 | | - if( $wgLang instanceof Language ) { |
| 2649 | + if ( $wgLang instanceof Language ) { |
2525 | 2650 | $cachederror = htmlspecialchars( $wgLang->getMessage( 'dberr-cachederror' ) ); |
2526 | 2651 | } |
| 2652 | + |
2527 | 2653 | $warning = "<div style='color:red;font-size:150%;font-weight:bold;'>$cachederror</div>"; |
| 2654 | + |
2528 | 2655 | # Output cached page with notices on bottom and re-close body |
2529 | 2656 | return "{$cache}{$warning}<hr />$text<hr />$extra</body></html>"; |
2530 | 2657 | } |
2531 | | - } catch( MWException $e ) { |
| 2658 | + } catch ( MWException $e ) { |
2532 | 2659 | // Do nothing, just use the default page |
2533 | 2660 | } |
2534 | 2661 | } |
| 2662 | + |
2535 | 2663 | # Headers needed here - output is just the error message |
2536 | | - return $this->htmlHeader()."$text<hr />$extra".$this->htmlFooter(); |
| 2664 | + return $this->htmlHeader() . "$text<hr />$extra" . $this->htmlFooter(); |
2537 | 2665 | } |
2538 | 2666 | |
2539 | 2667 | function searchForm() { |
2540 | 2668 | global $wgSitename, $wgServer, $wgLang, $wgInputEncoding; |
| 2669 | + |
2541 | 2670 | $usegoogle = "You can try searching via Google in the meantime."; |
2542 | 2671 | $outofdate = "Note that their indexes of our content may be out of date."; |
2543 | 2672 | $googlesearch = "Search"; |
— | — | @@ -2547,7 +2676,7 @@ |
2548 | 2677 | $googlesearch = htmlspecialchars( $wgLang->getMessage( 'searchbutton' ) ); |
2549 | 2678 | } |
2550 | 2679 | |
2551 | | - $search = htmlspecialchars(@$_REQUEST['search']); |
| 2680 | + $search = htmlspecialchars( @$_REQUEST['search'] ); |
2552 | 2681 | |
2553 | 2682 | $trygoogle = <<<EOT |
2554 | 2683 | <div style="margin: 1.5em">$usegoogle<br /> |
— | — | @@ -2573,22 +2702,27 @@ |
2574 | 2703 | |
2575 | 2704 | function fileCachedPage() { |
2576 | 2705 | global $wgTitle, $title, $wgLang, $wgOut; |
2577 | | - if( $wgOut->isDisabled() ) return; // Done already? |
| 2706 | + |
| 2707 | + if ( $wgOut->isDisabled() ) { |
| 2708 | + return; // Done already? |
| 2709 | + } |
| 2710 | + |
2578 | 2711 | $mainpage = 'Main Page'; |
| 2712 | + |
2579 | 2713 | if ( $wgLang instanceof Language ) { |
2580 | 2714 | $mainpage = htmlspecialchars( $wgLang->getMessage( 'mainpage' ) ); |
2581 | 2715 | } |
2582 | 2716 | |
2583 | | - if( $wgTitle ) { |
| 2717 | + if ( $wgTitle ) { |
2584 | 2718 | $t =& $wgTitle; |
2585 | | - } elseif( $title ) { |
| 2719 | + } elseif ( $title ) { |
2586 | 2720 | $t = Title::newFromURL( $title ); |
2587 | 2721 | } else { |
2588 | 2722 | $t = Title::newFromText( $mainpage ); |
2589 | 2723 | } |
2590 | 2724 | |
2591 | 2725 | $cache = new HTMLFileCache( $t ); |
2592 | | - if( $cache->isFileCached() ) { |
| 2726 | + if ( $cache->isFileCached() ) { |
2593 | 2727 | return $cache->fetchPageText(); |
2594 | 2728 | } else { |
2595 | 2729 | return ''; |
— | — | @@ -2598,7 +2732,6 @@ |
2599 | 2733 | function htmlBodyOnly() { |
2600 | 2734 | return true; |
2601 | 2735 | } |
2602 | | - |
2603 | 2736 | } |
2604 | 2737 | |
2605 | 2738 | /** |
— | — | @@ -2614,6 +2747,7 @@ |
2615 | 2748 | "Error: $errno $error\n"; |
2616 | 2749 | |
2617 | 2750 | parent::__construct( $db, $message ); |
| 2751 | + |
2618 | 2752 | $this->error = $error; |
2619 | 2753 | $this->errno = $errno; |
2620 | 2754 | $this->sql = $sql; |
— | — | @@ -2622,12 +2756,15 @@ |
2623 | 2757 | |
2624 | 2758 | function getText() { |
2625 | 2759 | global $wgShowDBErrorBacktrace; |
| 2760 | + |
2626 | 2761 | if ( $this->useMessageCache() ) { |
2627 | 2762 | $s = wfMsg( 'dberrortextcl', htmlspecialchars( $this->getSQL() ), |
2628 | 2763 | htmlspecialchars( $this->fname ), $this->errno, htmlspecialchars( $this->error ) ) . "\n"; |
| 2764 | + |
2629 | 2765 | if ( $wgShowDBErrorBacktrace ) { |
2630 | 2766 | $s .= "Backtrace:\n" . $this->getTraceAsString() . "\n"; |
2631 | 2767 | } |
| 2768 | + |
2632 | 2769 | return $s; |
2633 | 2770 | } else { |
2634 | 2771 | return parent::getText(); |
— | — | @@ -2636,7 +2773,8 @@ |
2637 | 2774 | |
2638 | 2775 | function getSQL() { |
2639 | 2776 | global $wgShowSQLErrors; |
2640 | | - if( !$wgShowSQLErrors ) { |
| 2777 | + |
| 2778 | + if ( !$wgShowSQLErrors ) { |
2641 | 2779 | return $this->msg( 'sqlhidden', 'SQL hidden' ); |
2642 | 2780 | } else { |
2643 | 2781 | return $this->sql; |
— | — | @@ -2654,15 +2792,18 @@ |
2655 | 2793 | |
2656 | 2794 | function getHTML() { |
2657 | 2795 | global $wgShowDBErrorBacktrace; |
| 2796 | + |
2658 | 2797 | if ( $this->useMessageCache() ) { |
2659 | 2798 | $s = wfMsgNoDB( 'dberrortext', htmlspecialchars( $this->getSQL() ), |
2660 | 2799 | htmlspecialchars( $this->fname ), $this->errno, htmlspecialchars( $this->error ) ); |
2661 | 2800 | } else { |
2662 | 2801 | $s = nl2br( htmlspecialchars( $this->getMessage() ) ); |
2663 | 2802 | } |
| 2803 | + |
2664 | 2804 | if ( $wgShowDBErrorBacktrace ) { |
2665 | 2805 | $s .= '<p>Backtrace:</p><p>' . nl2br( htmlspecialchars( $this->getTraceAsString() ) ); |
2666 | 2806 | } |
| 2807 | + |
2667 | 2808 | return $s; |
2668 | 2809 | } |
2669 | 2810 | } |
— | — | @@ -2685,6 +2826,7 @@ |
2686 | 2827 | */ |
2687 | 2828 | function __construct( $database, $result ) { |
2688 | 2829 | $this->db = $database; |
| 2830 | + |
2689 | 2831 | if ( $result instanceof ResultWrapper ) { |
2690 | 2832 | $this->result = $result->result; |
2691 | 2833 | } else { |
— | — | @@ -2746,8 +2888,8 @@ |
2747 | 2889 | */ |
2748 | 2890 | |
2749 | 2891 | function rewind() { |
2750 | | - if ($this->numRows()) { |
2751 | | - $this->db->dataSeek($this, 0); |
| 2892 | + if ( $this->numRows() ) { |
| 2893 | + $this->db->dataSeek( $this, 0 ); |
2752 | 2894 | } |
2753 | 2895 | $this->pos = 0; |
2754 | 2896 | $this->currentRow = null; |
— | — | @@ -2775,17 +2917,17 @@ |
2776 | 2918 | } |
2777 | 2919 | } |
2778 | 2920 | |
2779 | | -/* Overloads the relevant methods of the real ResultsWrapper so it |
| 2921 | +/** |
| 2922 | + * Overloads the relevant methods of the real ResultsWrapper so it |
2780 | 2923 | * doesn't go anywhere near an actual database. |
2781 | 2924 | */ |
2782 | 2925 | class FakeResultWrapper extends ResultWrapper { |
2783 | | - |
2784 | 2926 | var $result = array(); |
2785 | 2927 | var $db = null; // And it's going to stay that way :D |
2786 | 2928 | var $pos = 0; |
2787 | 2929 | var $currentRow = null; |
2788 | 2930 | |
2789 | | - function __construct( $array ){ |
| 2931 | + function __construct( $array ) { |
2790 | 2932 | $this->result = $array; |
2791 | 2933 | } |
2792 | 2934 | |
— | — | @@ -2805,7 +2947,7 @@ |
2806 | 2948 | function free() {} |
2807 | 2949 | |
2808 | 2950 | // Callers want to be able to access fields with $this->fieldName |
2809 | | - function fetchObject(){ |
| 2951 | + function fetchObject() { |
2810 | 2952 | $this->currentRow = $this->result[$this->pos++]; |
2811 | 2953 | return (object)$this->currentRow; |
2812 | 2954 | } |
Index: trunk/phase3/includes/filerepo/LocalFile.php |
— | — | @@ -71,6 +71,7 @@ |
72 | 72 | $title = Title::makeTitle( NS_FILE, $row->img_name ); |
73 | 73 | $file = new self( $title, $repo ); |
74 | 74 | $file->loadFromRow( $row ); |
| 75 | + |
75 | 76 | return $file; |
76 | 77 | } |
77 | 78 | |
— | — | @@ -80,12 +81,15 @@ |
81 | 82 | */ |
82 | 83 | static function newFromKey( $sha1, $repo, $timestamp = false ) { |
83 | 84 | $conds = array( 'img_sha1' => $sha1 ); |
84 | | - if( $timestamp ) { |
| 85 | + |
| 86 | + if ( $timestamp ) { |
85 | 87 | $conds['img_timestamp'] = $timestamp; |
86 | 88 | } |
| 89 | + |
87 | 90 | $dbr = $repo->getSlaveDB(); |
88 | 91 | $row = $dbr->selectRow( 'image', self::selectFields(), $conds, __METHOD__ ); |
89 | | - if( $row ) { |
| 92 | + |
| 93 | + if ( $row ) { |
90 | 94 | return self::newFromRow( $row, $repo ); |
91 | 95 | } else { |
92 | 96 | return false; |
— | — | @@ -119,10 +123,12 @@ |
120 | 124 | * Do not call this except from inside a repo class. |
121 | 125 | */ |
122 | 126 | function __construct( $title, $repo ) { |
123 | | - if( !is_object( $title ) ) { |
| 127 | + if ( !is_object( $title ) ) { |
124 | 128 | throw new MWException( __CLASS__ . ' constructor given bogus title.' ); |
125 | 129 | } |
| 130 | + |
126 | 131 | parent::__construct( $title, $repo ); |
| 132 | + |
127 | 133 | $this->metadata = ''; |
128 | 134 | $this->historyLine = 0; |
129 | 135 | $this->historyRes = null; |
— | — | @@ -135,6 +141,7 @@ |
136 | 142 | */ |
137 | 143 | function getCacheKey() { |
138 | 144 | $hashedName = md5( $this->getName() ); |
| 145 | + |
139 | 146 | return $this->repo->getSharedCacheKey( 'file', $hashedName ); |
140 | 147 | } |
141 | 148 | |
— | — | @@ -143,13 +150,16 @@ |
144 | 151 | */ |
145 | 152 | function loadFromCache() { |
146 | 153 | global $wgMemc; |
| 154 | + |
147 | 155 | wfProfileIn( __METHOD__ ); |
148 | 156 | $this->dataLoaded = false; |
149 | 157 | $key = $this->getCacheKey(); |
| 158 | + |
150 | 159 | if ( !$key ) { |
151 | 160 | wfProfileOut( __METHOD__ ); |
152 | 161 | return false; |
153 | 162 | } |
| 163 | + |
154 | 164 | $cachedValues = $wgMemc->get( $key ); |
155 | 165 | |
156 | 166 | // Check if the key existed and belongs to this version of MediaWiki |
— | — | @@ -161,6 +171,7 @@ |
162 | 172 | } |
163 | 173 | $this->dataLoaded = true; |
164 | 174 | } |
| 175 | + |
165 | 176 | if ( $this->dataLoaded ) { |
166 | 177 | wfIncrStats( 'image_cache_hit' ); |
167 | 178 | } else { |
— | — | @@ -176,14 +187,18 @@ |
177 | 188 | */ |
178 | 189 | function saveToCache() { |
179 | 190 | global $wgMemc; |
| 191 | + |
180 | 192 | $this->load(); |
181 | 193 | $key = $this->getCacheKey(); |
| 194 | + |
182 | 195 | if ( !$key ) { |
183 | 196 | return; |
184 | 197 | } |
| 198 | + |
185 | 199 | $fields = $this->getCacheFields( '' ); |
186 | 200 | $cache = array( 'version' => MW_FILE_VERSION ); |
187 | 201 | $cache['fileExists'] = $this->fileExists; |
| 202 | + |
188 | 203 | if ( $this->fileExists ) { |
189 | 204 | foreach ( $fields as $field ) { |
190 | 205 | $cache[$field] = $this->$field; |
— | — | @@ -204,9 +219,11 @@ |
205 | 220 | static $fields = array( 'size', 'width', 'height', 'bits', 'media_type', |
206 | 221 | 'major_mime', 'minor_mime', 'metadata', 'timestamp', 'sha1', 'user', 'user_text', 'description' ); |
207 | 222 | static $results = array(); |
| 223 | + |
208 | 224 | if ( $prefix == '' ) { |
209 | 225 | return $fields; |
210 | 226 | } |
| 227 | + |
211 | 228 | if ( !isset( $results[$prefix] ) ) { |
212 | 229 | $prefixedFields = array(); |
213 | 230 | foreach ( $fields as $field ) { |
— | — | @@ -214,6 +231,7 @@ |
215 | 232 | } |
216 | 233 | $results[$prefix] = $prefixedFields; |
217 | 234 | } |
| 235 | + |
218 | 236 | return $results[$prefix]; |
219 | 237 | } |
220 | 238 | |
— | — | @@ -232,6 +250,7 @@ |
233 | 251 | |
234 | 252 | $row = $dbr->selectRow( 'image', $this->getCacheFields( 'img_' ), |
235 | 253 | array( 'img_name' => $this->getName() ), $fname ); |
| 254 | + |
236 | 255 | if ( $row ) { |
237 | 256 | $this->loadFromRow( $row ); |
238 | 257 | } else { |
— | — | @@ -248,15 +267,20 @@ |
249 | 268 | function decodeRow( $row, $prefix = 'img_' ) { |
250 | 269 | $array = (array)$row; |
251 | 270 | $prefixLength = strlen( $prefix ); |
| 271 | + |
252 | 272 | // Sanity check prefix once |
253 | 273 | if ( substr( key( $array ), 0, $prefixLength ) !== $prefix ) { |
254 | 274 | throw new MWException( __METHOD__ . ': incorrect $prefix parameter' ); |
255 | 275 | } |
| 276 | + |
256 | 277 | $decoded = array(); |
| 278 | + |
257 | 279 | foreach ( $array as $name => $value ) { |
258 | 280 | $decoded[substr( $name, $prefixLength )] = $value; |
259 | 281 | } |
| 282 | + |
260 | 283 | $decoded['timestamp'] = wfTimestamp( TS_MW, $decoded['timestamp'] ); |
| 284 | + |
261 | 285 | if ( empty( $decoded['major_mime'] ) ) { |
262 | 286 | $decoded['mime'] = 'unknown/unknown'; |
263 | 287 | } else { |
— | — | @@ -265,8 +289,10 @@ |
266 | 290 | } |
267 | 291 | $decoded['mime'] = $decoded['major_mime'] . '/' . $decoded['minor_mime']; |
268 | 292 | } |
| 293 | + |
269 | 294 | # Trim zero padding from char/binary field |
270 | 295 | $decoded['sha1'] = rtrim( $decoded['sha1'], "\0" ); |
| 296 | + |
271 | 297 | return $decoded; |
272 | 298 | } |
273 | 299 | |
— | — | @@ -276,9 +302,11 @@ |
277 | 303 | function loadFromRow( $row, $prefix = 'img_' ) { |
278 | 304 | $this->dataLoaded = true; |
279 | 305 | $array = $this->decodeRow( $row, $prefix ); |
| 306 | + |
280 | 307 | foreach ( $array as $name => $value ) { |
281 | 308 | $this->$name = $value; |
282 | 309 | } |
| 310 | + |
283 | 311 | $this->fileExists = true; |
284 | 312 | $this->maybeUpgradeRow(); |
285 | 313 | } |
— | — | @@ -303,6 +331,7 @@ |
304 | 332 | if ( wfReadOnly() ) { |
305 | 333 | return; |
306 | 334 | } |
| 335 | + |
307 | 336 | if ( is_null( $this->media_type ) || |
308 | 337 | $this->mime == 'image/svg' |
309 | 338 | ) { |
— | — | @@ -335,6 +364,7 @@ |
336 | 365 | wfProfileOut( __METHOD__ ); |
337 | 366 | return; |
338 | 367 | } |
| 368 | + |
339 | 369 | $dbw = $this->repo->getMasterDB(); |
340 | 370 | list( $major, $minor ) = self::splitMime( $this->mime ); |
341 | 371 | |
— | — | @@ -357,6 +387,7 @@ |
358 | 388 | ), array( 'img_name' => $this->getName() ), |
359 | 389 | __METHOD__ |
360 | 390 | ); |
| 391 | + |
361 | 392 | $this->saveToCache(); |
362 | 393 | wfProfileOut( __METHOD__ ); |
363 | 394 | } |
— | — | @@ -372,6 +403,7 @@ |
373 | 404 | $this->dataLoaded = true; |
374 | 405 | $fields = $this->getCacheFields( '' ); |
375 | 406 | $fields[] = 'fileExists'; |
| 407 | + |
376 | 408 | foreach ( $fields as $field ) { |
377 | 409 | if ( isset( $info[$field] ) ) { |
378 | 410 | $this->$field = $info[$field]; |
— | — | @@ -396,7 +428,7 @@ |
397 | 429 | /** isVisible inhereted */ |
398 | 430 | |
399 | 431 | function isMissing() { |
400 | | - if( $this->missing === null ) { |
| 432 | + if ( $this->missing === null ) { |
401 | 433 | list( $fileExists ) = $this->repo->fileExistsBatch( array( $this->getVirtualUrl() ), FileRepo::FILES_ONLY ); |
402 | 434 | $this->missing = !$fileExists; |
403 | 435 | } |
— | — | @@ -410,6 +442,7 @@ |
411 | 443 | */ |
412 | 444 | public function getWidth( $page = 1 ) { |
413 | 445 | $this->load(); |
| 446 | + |
414 | 447 | if ( $this->isMultipage() ) { |
415 | 448 | $dim = $this->getHandler()->getPageDimensions( $this, $page ); |
416 | 449 | if ( $dim ) { |
— | — | @@ -429,6 +462,7 @@ |
430 | 463 | */ |
431 | 464 | public function getHeight( $page = 1 ) { |
432 | 465 | $this->load(); |
| 466 | + |
433 | 467 | if ( $this->isMultipage() ) { |
434 | 468 | $dim = $this->getHandler()->getPageDimensions( $this, $page ); |
435 | 469 | if ( $dim ) { |
— | — | @@ -448,9 +482,10 @@ |
449 | 483 | */ |
450 | 484 | function getUser( $type = 'text' ) { |
451 | 485 | $this->load(); |
452 | | - if( $type == 'text' ) { |
| 486 | + |
| 487 | + if ( $type == 'text' ) { |
453 | 488 | return $this->user_text; |
454 | | - } elseif( $type == 'id' ) { |
| 489 | + } elseif ( $type == 'id' ) { |
455 | 490 | return $this->user; |
456 | 491 | } |
457 | 492 | } |
— | — | @@ -521,6 +556,7 @@ |
522 | 557 | function migrateThumbFile( $thumbName ) { |
523 | 558 | $thumbDir = $this->getThumbPath(); |
524 | 559 | $thumbPath = "$thumbDir/$thumbName"; |
| 560 | + |
525 | 561 | if ( is_dir( $thumbPath ) ) { |
526 | 562 | // Directory where file should be |
527 | 563 | // This happened occasionally due to broken migration code in 1.5 |
— | — | @@ -535,6 +571,7 @@ |
536 | 572 | // Doesn't exist anymore |
537 | 573 | clearstatcache(); |
538 | 574 | } |
| 575 | + |
539 | 576 | if ( is_file( $thumbDir ) ) { |
540 | 577 | // File where directory should be |
541 | 578 | unlink( $thumbDir ); |
— | — | @@ -552,6 +589,7 @@ |
553 | 590 | */ |
554 | 591 | function getThumbnails() { |
555 | 592 | $this->load(); |
| 593 | + |
556 | 594 | $files = array(); |
557 | 595 | $dir = $this->getThumbPath(); |
558 | 596 | |
— | — | @@ -560,10 +598,11 @@ |
561 | 599 | |
562 | 600 | if ( $handle ) { |
563 | 601 | while ( false !== ( $file = readdir( $handle ) ) ) { |
564 | | - if ( $file{0} != '.' ) { |
| 602 | + if ( $file { 0 } != '.' ) { |
565 | 603 | $files[] = $file; |
566 | 604 | } |
567 | 605 | } |
| 606 | + |
568 | 607 | closedir( $handle ); |
569 | 608 | } |
570 | 609 | } |
— | — | @@ -585,8 +624,10 @@ |
586 | 625 | */ |
587 | 626 | function purgeHistory() { |
588 | 627 | global $wgMemc; |
| 628 | + |
589 | 629 | $hashedName = md5( $this->getName() ); |
590 | 630 | $oldKey = $this->repo->getSharedCacheKey( 'oldfile', $hashedName ); |
| 631 | + |
591 | 632 | if ( $oldKey ) { |
592 | 633 | $wgMemc->delete( $oldKey ); |
593 | 634 | } |
— | — | @@ -611,10 +652,12 @@ |
612 | 653 | */ |
613 | 654 | function purgeThumbnails() { |
614 | 655 | global $wgUseSquid; |
| 656 | + |
615 | 657 | // Delete thumbnails |
616 | 658 | $files = $this->getThumbnails(); |
617 | 659 | $dir = $this->getThumbPath(); |
618 | 660 | $urls = array(); |
| 661 | + |
619 | 662 | foreach ( $files as $file ) { |
620 | 663 | # Check that the base file name is part of the thumb name |
621 | 664 | # This is a basic sanity check to avoid erasing unrelated directories |
— | — | @@ -641,15 +684,19 @@ |
642 | 685 | $conds = $opts = $join_conds = array(); |
643 | 686 | $eq = $inc ? '=' : ''; |
644 | 687 | $conds[] = "oi_name = " . $dbr->addQuotes( $this->title->getDBkey() ); |
645 | | - if( $start ) { |
| 688 | + |
| 689 | + if ( $start ) { |
646 | 690 | $conds[] = "oi_timestamp <$eq " . $dbr->addQuotes( $dbr->timestamp( $start ) ); |
647 | 691 | } |
648 | | - if( $end ) { |
| 692 | + |
| 693 | + if ( $end ) { |
649 | 694 | $conds[] = "oi_timestamp >$eq " . $dbr->addQuotes( $dbr->timestamp( $end ) ); |
650 | 695 | } |
651 | | - if( $limit ) { |
| 696 | + |
| 697 | + if ( $limit ) { |
652 | 698 | $opts['LIMIT'] = $limit; |
653 | 699 | } |
| 700 | + |
654 | 701 | // Search backwards for time > x queries |
655 | 702 | $order = ( !$start && $end !== null ) ? 'ASC' : 'DESC'; |
656 | 703 | $opts['ORDER BY'] = "oi_timestamp $order"; |
— | — | @@ -660,16 +707,19 @@ |
661 | 708 | |
662 | 709 | $res = $dbr->select( $tables, $fields, $conds, __METHOD__, $opts, $join_conds ); |
663 | 710 | $r = array(); |
664 | | - while( $row = $dbr->fetchObject( $res ) ) { |
| 711 | + |
| 712 | + while ( $row = $dbr->fetchObject( $res ) ) { |
665 | 713 | if ( $this->repo->oldFileFromRowFactory ) { |
666 | 714 | $r[] = call_user_func( $this->repo->oldFileFromRowFactory, $row, $this->repo ); |
667 | 715 | } else { |
668 | 716 | $r[] = OldLocalFile::newFromRow( $row, $this->repo ); |
669 | 717 | } |
670 | 718 | } |
671 | | - if( $order == 'ASC' ) { |
| 719 | + |
| 720 | + if ( $order == 'ASC' ) { |
672 | 721 | $r = array_reverse( $r ); // make sure it ends up descending |
673 | 722 | } |
| 723 | + |
674 | 724 | return $r; |
675 | 725 | } |
676 | 726 | |
— | — | @@ -698,6 +748,7 @@ |
699 | 749 | array( 'img_name' => $this->title->getDBkey() ), |
700 | 750 | $fname |
701 | 751 | ); |
| 752 | + |
702 | 753 | if ( 0 == $dbr->numRows( $this->historyRes ) ) { |
703 | 754 | $this->historyRes = null; |
704 | 755 | return false; |
— | — | @@ -719,6 +770,7 @@ |
720 | 771 | */ |
721 | 772 | public function resetHistory() { |
722 | 773 | $this->historyLine = 0; |
| 774 | + |
723 | 775 | if ( !is_null( $this->historyRes ) ) { |
724 | 776 | $this->historyRes = null; |
725 | 777 | } |
— | — | @@ -757,12 +809,15 @@ |
758 | 810 | function upload( $srcPath, $comment, $pageText, $flags = 0, $props = false, $timestamp = false, $user = null ) { |
759 | 811 | $this->lock(); |
760 | 812 | $status = $this->publish( $srcPath, $flags ); |
| 813 | + |
761 | 814 | if ( $status->ok ) { |
762 | 815 | if ( !$this->recordUpload2( $status->value, $comment, $pageText, $props, $timestamp, $user ) ) { |
763 | 816 | $status->fatal( 'filenotfound', $srcPath ); |
764 | 817 | } |
765 | 818 | } |
| 819 | + |
766 | 820 | $this->unlock(); |
| 821 | + |
767 | 822 | return $status; |
768 | 823 | } |
769 | 824 | |
— | — | @@ -774,9 +829,11 @@ |
775 | 830 | $watch = false, $timestamp = false ) |
776 | 831 | { |
777 | 832 | $pageText = SpecialUpload::getInitialPageText( $desc, $license, $copyStatus, $source ); |
| 833 | + |
778 | 834 | if ( !$this->recordUpload2( $oldver, $desc, $pageText ) ) { |
779 | 835 | return false; |
780 | 836 | } |
| 837 | + |
781 | 838 | if ( $watch ) { |
782 | 839 | global $wgUser; |
783 | 840 | $wgUser->addWatch( $this->getTitle() ); |
— | — | @@ -790,7 +847,7 @@ |
791 | 848 | */ |
792 | 849 | function recordUpload2( $oldver, $comment, $pageText, $props = false, $timestamp = false, $user = null ) |
793 | 850 | { |
794 | | - if( is_null( $user ) ) { |
| 851 | + if ( is_null( $user ) ) { |
795 | 852 | global $wgUser; |
796 | 853 | $user = $wgUser; |
797 | 854 | } |
— | — | @@ -801,6 +858,7 @@ |
802 | 859 | if ( !$props ) { |
803 | 860 | $props = $this->repo->getFileProps( $this->getVirtualUrl() ); |
804 | 861 | } |
| 862 | + |
805 | 863 | $props['description'] = $comment; |
806 | 864 | $props['user'] = $user->getId(); |
807 | 865 | $props['user_text'] = $user->getName(); |
— | — | @@ -809,6 +867,7 @@ |
810 | 868 | |
811 | 869 | # Delete thumbnails |
812 | 870 | $this->purgeThumbnails(); |
| 871 | + |
813 | 872 | # The file is already on its final location, remove it from the squid cache |
814 | 873 | SquidUpdate::purge( array( $this->getURL() ) ); |
815 | 874 | |
— | — | @@ -819,6 +878,7 @@ |
820 | 879 | } |
821 | 880 | |
822 | 881 | $reupload = false; |
| 882 | + |
823 | 883 | if ( $timestamp === false ) { |
824 | 884 | $timestamp = $dbw->timestamp(); |
825 | 885 | } |
— | — | @@ -829,7 +889,7 @@ |
830 | 890 | $dbw->insert( 'image', |
831 | 891 | array( |
832 | 892 | 'img_name' => $this->getName(), |
833 | | - 'img_size'=> $this->size, |
| 893 | + 'img_size' => $this->size, |
834 | 894 | 'img_width' => intval( $this->width ), |
835 | 895 | 'img_height' => intval( $this->height ), |
836 | 896 | 'img_bits' => $this->bits, |
— | — | @@ -847,7 +907,7 @@ |
848 | 908 | 'IGNORE' |
849 | 909 | ); |
850 | 910 | |
851 | | - if( $dbw->affectedRows() == 0 ) { |
| 911 | + if ( $dbw->affectedRows() == 0 ) { |
852 | 912 | $reupload = true; |
853 | 913 | |
854 | 914 | # Collision, this is an update of a file |
— | — | @@ -908,11 +968,15 @@ |
909 | 969 | $action = $reupload ? 'overwrite' : 'upload'; |
910 | 970 | $log->addEntry( $action, $descTitle, $comment, array(), $user ); |
911 | 971 | |
912 | | - if( $descTitle->exists() ) { |
| 972 | + if ( $descTitle->exists() ) { |
913 | 973 | # Create a null revision |
914 | 974 | $latest = $descTitle->getLatestRevID(); |
915 | | - $nullRevision = Revision::newNullRevision( $dbw, $descTitle->getArticleId(), |
916 | | - $log->getRcComment(), false ); |
| 975 | + $nullRevision = Revision::newNullRevision( |
| 976 | + $dbw, |
| 977 | + $descTitle->getArticleId(), |
| 978 | + $log->getRcComment(), |
| 979 | + false |
| 980 | + ); |
917 | 981 | $nullRevision->insertOn( $dbw ); |
918 | 982 | |
919 | 983 | wfRunHooks( 'NewRevisionFromEditComplete', array( $article, $nullRevision, $latest, $user ) ); |
— | — | @@ -937,16 +1001,18 @@ |
938 | 1002 | # in case of a rollback there is an usable file from memcached |
939 | 1003 | # which in fact doesn't really exist (bug 24978) |
940 | 1004 | $this->saveToCache(); |
941 | | - |
| 1005 | + |
942 | 1006 | # Hooks, hooks, the magic of hooks... |
943 | 1007 | wfRunHooks( 'FileUpload', array( $this, $reupload, $descTitle->exists() ) ); |
944 | 1008 | |
945 | 1009 | # Invalidate cache for all pages using this file |
946 | 1010 | $update = new HTMLCacheUpdate( $this->getTitle(), 'imagelinks' ); |
947 | 1011 | $update->doUpdate(); |
| 1012 | + |
948 | 1013 | # Invalidate cache for all pages that redirects on this page |
949 | 1014 | $redirs = $this->getTitle()->getRedirectsHere(); |
950 | | - foreach( $redirs as $redir ) { |
| 1015 | + |
| 1016 | + foreach ( $redirs as $redir ) { |
951 | 1017 | $update = new HTMLCacheUpdate( $redir, 'imagelinks' ); |
952 | 1018 | $update->doUpdate(); |
953 | 1019 | } |
— | — | @@ -971,17 +1037,21 @@ |
972 | 1038 | */ |
973 | 1039 | function publish( $srcPath, $flags = 0 ) { |
974 | 1040 | $this->lock(); |
| 1041 | + |
975 | 1042 | $dstRel = $this->getRel(); |
976 | | - $archiveName = gmdate( 'YmdHis' ) . '!'. $this->getName(); |
| 1043 | + $archiveName = gmdate( 'YmdHis' ) . '!' . $this->getName(); |
977 | 1044 | $archiveRel = 'archive/' . $this->getHashPath() . $archiveName; |
978 | 1045 | $flags = $flags & File::DELETE_SOURCE ? LocalRepo::DELETE_SOURCE : 0; |
979 | 1046 | $status = $this->repo->publish( $srcPath, $dstRel, $archiveRel, $flags ); |
| 1047 | + |
980 | 1048 | if ( $status->value == 'new' ) { |
981 | 1049 | $status->value = ''; |
982 | 1050 | } else { |
983 | 1051 | $status->value = $archiveName; |
984 | 1052 | } |
| 1053 | + |
985 | 1054 | $this->unlock(); |
| 1055 | + |
986 | 1056 | return $status; |
987 | 1057 | } |
988 | 1058 | |
— | — | @@ -1005,12 +1075,14 @@ |
1006 | 1076 | function move( $target ) { |
1007 | 1077 | wfDebugLog( 'imagemove', "Got request to move {$this->name} to " . $target->getText() ); |
1008 | 1078 | $this->lock(); |
| 1079 | + |
1009 | 1080 | $batch = new LocalFileMoveBatch( $this, $target ); |
1010 | 1081 | $batch->addCurrent(); |
1011 | 1082 | $batch->addOlds(); |
1012 | 1083 | |
1013 | 1084 | $status = $batch->execute(); |
1014 | 1085 | wfDebugLog( 'imagemove', "Finished moving {$this->name}" ); |
| 1086 | + |
1015 | 1087 | $this->purgeEverything(); |
1016 | 1088 | $this->unlock(); |
1017 | 1089 | |
— | — | @@ -1041,6 +1113,7 @@ |
1042 | 1114 | */ |
1043 | 1115 | function delete( $reason, $suppress = false ) { |
1044 | 1116 | $this->lock(); |
| 1117 | + |
1045 | 1118 | $batch = new LocalFileDeleteBatch( $this, $reason, $suppress ); |
1046 | 1119 | $batch->addCurrent(); |
1047 | 1120 | |
— | — | @@ -1062,6 +1135,7 @@ |
1063 | 1136 | } |
1064 | 1137 | |
1065 | 1138 | $this->unlock(); |
| 1139 | + |
1066 | 1140 | return $status; |
1067 | 1141 | } |
1068 | 1142 | |
— | — | @@ -1079,16 +1153,20 @@ |
1080 | 1154 | * @throws MWException or FSException on database or file store failure |
1081 | 1155 | * @return FileRepoStatus object. |
1082 | 1156 | */ |
1083 | | - function deleteOld( $archiveName, $reason, $suppress=false ) { |
| 1157 | + function deleteOld( $archiveName, $reason, $suppress = false ) { |
1084 | 1158 | $this->lock(); |
| 1159 | + |
1085 | 1160 | $batch = new LocalFileDeleteBatch( $this, $reason, $suppress ); |
1086 | 1161 | $batch->addOld( $archiveName ); |
1087 | 1162 | $status = $batch->execute(); |
| 1163 | + |
1088 | 1164 | $this->unlock(); |
| 1165 | + |
1089 | 1166 | if ( $status->ok ) { |
1090 | 1167 | $this->purgeDescription(); |
1091 | 1168 | $this->purgeHistory(); |
1092 | 1169 | } |
| 1170 | + |
1093 | 1171 | return $status; |
1094 | 1172 | } |
1095 | 1173 | |
— | — | @@ -1105,12 +1183,15 @@ |
1106 | 1184 | */ |
1107 | 1185 | function restore( $versions = array(), $unsuppress = false ) { |
1108 | 1186 | $batch = new LocalFileRestoreBatch( $this, $unsuppress ); |
| 1187 | + |
1109 | 1188 | if ( !$versions ) { |
1110 | 1189 | $batch->addAll(); |
1111 | 1190 | } else { |
1112 | 1191 | $batch->addIds( $versions ); |
1113 | 1192 | } |
| 1193 | + |
1114 | 1194 | $status = $batch->execute(); |
| 1195 | + |
1115 | 1196 | if ( !$status->ok ) { |
1116 | 1197 | return $status; |
1117 | 1198 | } |
— | — | @@ -1119,6 +1200,7 @@ |
1120 | 1201 | $cleanupStatus->successCount = 0; |
1121 | 1202 | $cleanupStatus->failCount = 0; |
1122 | 1203 | $status->merge( $cleanupStatus ); |
| 1204 | + |
1123 | 1205 | return $status; |
1124 | 1206 | } |
1125 | 1207 | |
— | — | @@ -1165,10 +1247,12 @@ |
1166 | 1248 | */ |
1167 | 1249 | function lock() { |
1168 | 1250 | $dbw = $this->repo->getMasterDB(); |
| 1251 | + |
1169 | 1252 | if ( !$this->locked ) { |
1170 | 1253 | $dbw->begin(); |
1171 | 1254 | $this->locked++; |
1172 | 1255 | } |
| 1256 | + |
1173 | 1257 | return $dbw->selectField( 'image', '1', array( 'img_name' => $this->getName() ), __METHOD__ ); |
1174 | 1258 | } |
1175 | 1259 | |
— | — | @@ -1196,7 +1280,7 @@ |
1197 | 1281 | } |
1198 | 1282 | } // LocalFile class |
1199 | 1283 | |
1200 | | -#------------------------------------------------------------------------------ |
| 1284 | +# ------------------------------------------------------------------------------ |
1201 | 1285 | |
1202 | 1286 | /** |
1203 | 1287 | * Helper class for file deletion |
— | — | @@ -1231,25 +1315,33 @@ |
1232 | 1316 | unset( $oldRels['.'] ); |
1233 | 1317 | $deleteCurrent = true; |
1234 | 1318 | } |
| 1319 | + |
1235 | 1320 | return array( $oldRels, $deleteCurrent ); |
1236 | 1321 | } |
1237 | 1322 | |
1238 | 1323 | /*protected*/ function getHashes() { |
1239 | 1324 | $hashes = array(); |
1240 | 1325 | list( $oldRels, $deleteCurrent ) = $this->getOldRels(); |
| 1326 | + |
1241 | 1327 | if ( $deleteCurrent ) { |
1242 | 1328 | $hashes['.'] = $this->file->getSha1(); |
1243 | 1329 | } |
| 1330 | + |
1244 | 1331 | if ( count( $oldRels ) ) { |
1245 | 1332 | $dbw = $this->file->repo->getMasterDB(); |
1246 | | - $res = $dbw->select( 'oldimage', array( 'oi_archive_name', 'oi_sha1' ), |
1247 | | - 'oi_archive_name IN(' . $dbw->makeList( array_keys( $oldRels ) ) . ')', |
1248 | | - __METHOD__ ); |
| 1333 | + $res = $dbw->select( |
| 1334 | + 'oldimage', |
| 1335 | + array( 'oi_archive_name', 'oi_sha1' ), |
| 1336 | + 'oi_archive_name IN (' . $dbw->makeList( array_keys( $oldRels ) ) . ')', |
| 1337 | + __METHOD__ |
| 1338 | + ); |
| 1339 | + |
1249 | 1340 | while ( $row = $dbw->fetchObject( $res ) ) { |
1250 | 1341 | if ( rtrim( $row->oi_sha1, "\0" ) === '' ) { |
1251 | 1342 | // Get the hash from the file |
1252 | 1343 | $oldUrl = $this->file->getArchiveVirtualUrl( $row->oi_archive_name ); |
1253 | 1344 | $props = $this->file->repo->getFileProps( $oldUrl ); |
| 1345 | + |
1254 | 1346 | if ( $props['fileExists'] ) { |
1255 | 1347 | // Upgrade the oldimage row |
1256 | 1348 | $dbw->update( 'oldimage', |
— | — | @@ -1265,10 +1357,13 @@ |
1266 | 1358 | } |
1267 | 1359 | } |
1268 | 1360 | } |
| 1361 | + |
1269 | 1362 | $missing = array_diff_key( $this->srcRels, $hashes ); |
| 1363 | + |
1270 | 1364 | foreach ( $missing as $name => $rel ) { |
1271 | 1365 | $this->status->error( 'filedelete-old-unregistered', $name ); |
1272 | 1366 | } |
| 1367 | + |
1273 | 1368 | foreach ( $hashes as $name => $hash ) { |
1274 | 1369 | if ( !$hash ) { |
1275 | 1370 | $this->status->error( 'filedelete-missing', $this->srcRels[$name] ); |
— | — | @@ -1281,6 +1376,7 @@ |
1282 | 1377 | |
1283 | 1378 | function doDBInserts() { |
1284 | 1379 | global $wgUser; |
| 1380 | + |
1285 | 1381 | $dbw = $this->file->repo->getMasterDB(); |
1286 | 1382 | $encTimestamp = $dbw->addQuotes( $dbw->timestamp() ); |
1287 | 1383 | $encUserId = $dbw->addQuotes( $wgUser->getId() ); |
— | — | @@ -1368,6 +1464,7 @@ |
1369 | 1465 | function doDBDeletes() { |
1370 | 1466 | $dbw = $this->file->repo->getMasterDB(); |
1371 | 1467 | list( $oldRels, $deleteCurrent ) = $this->getOldRels(); |
| 1468 | + |
1372 | 1469 | if ( count( $oldRels ) ) { |
1373 | 1470 | $dbw->delete( 'oldimage', |
1374 | 1471 | array( |
— | — | @@ -1375,6 +1472,7 @@ |
1376 | 1473 | 'oi_archive_name' => array_keys( $oldRels ) |
1377 | 1474 | ), __METHOD__ ); |
1378 | 1475 | } |
| 1476 | + |
1379 | 1477 | if ( $deleteCurrent ) { |
1380 | 1478 | $dbw->delete( 'image', array( 'img_name' => $this->file->getName() ), __METHOD__ ); |
1381 | 1479 | } |
— | — | @@ -1392,14 +1490,16 @@ |
1393 | 1491 | $privateFiles = array(); |
1394 | 1492 | list( $oldRels, $deleteCurrent ) = $this->getOldRels(); |
1395 | 1493 | $dbw = $this->file->repo->getMasterDB(); |
1396 | | - if( !empty( $oldRels ) ) { |
| 1494 | + |
| 1495 | + if ( !empty( $oldRels ) ) { |
1397 | 1496 | $res = $dbw->select( 'oldimage', |
1398 | 1497 | array( 'oi_archive_name' ), |
1399 | 1498 | array( 'oi_name' => $this->file->getName(), |
1400 | | - 'oi_archive_name IN (' . $dbw->makeList( array_keys($oldRels) ) . ')', |
1401 | | - $dbw->bitAnd('oi_deleted', File::DELETED_FILE) => File::DELETED_FILE ), |
| 1499 | + 'oi_archive_name IN (' . $dbw->makeList( array_keys( $oldRels ) ) . ')', |
| 1500 | + $dbw->bitAnd( 'oi_deleted', File::DELETED_FILE ) => File::DELETED_FILE ), |
1402 | 1501 | __METHOD__ ); |
1403 | | - while( $row = $dbw->fetchObject( $res ) ) { |
| 1502 | + |
| 1503 | + while ( $row = $dbw->fetchObject( $res ) ) { |
1404 | 1504 | $privateFiles[$row->oi_archive_name] = 1; |
1405 | 1505 | } |
1406 | 1506 | } |
— | — | @@ -1408,6 +1508,7 @@ |
1409 | 1509 | $this->deletionBatch = array(); |
1410 | 1510 | $ext = $this->file->getExtension(); |
1411 | 1511 | $dotExt = $ext === '' ? '' : ".$ext"; |
| 1512 | + |
1412 | 1513 | foreach ( $this->srcRels as $name => $srcRel ) { |
1413 | 1514 | // Skip files that have no hash (missing source). |
1414 | 1515 | // Keep private files where they are. |
— | — | @@ -1432,6 +1533,7 @@ |
1433 | 1534 | |
1434 | 1535 | // Execute the file deletion batch |
1435 | 1536 | $status = $this->file->repo->deleteBatch( $this->deletionBatch ); |
| 1537 | + |
1436 | 1538 | if ( !$status->isGood() ) { |
1437 | 1539 | $this->status->merge( $status ); |
1438 | 1540 | } |
— | — | @@ -1448,6 +1550,7 @@ |
1449 | 1551 | // Purge squid |
1450 | 1552 | if ( $wgUseSquid ) { |
1451 | 1553 | $urls = array(); |
| 1554 | + |
1452 | 1555 | foreach ( $this->srcRels as $srcRel ) { |
1453 | 1556 | $urlRel = str_replace( '%2F', '/', rawurlencode( $srcRel ) ); |
1454 | 1557 | $urls[] = $this->file->repo->getZoneUrl( 'public' ) . '/' . $urlRel; |
— | — | @@ -1461,6 +1564,7 @@ |
1462 | 1565 | // Commit and return |
1463 | 1566 | $this->file->unlock(); |
1464 | 1567 | wfProfileOut( __METHOD__ ); |
| 1568 | + |
1465 | 1569 | return $this->status; |
1466 | 1570 | } |
1467 | 1571 | |
— | — | @@ -1469,19 +1573,25 @@ |
1470 | 1574 | */ |
1471 | 1575 | function removeNonexistentFiles( $batch ) { |
1472 | 1576 | $files = $newBatch = array(); |
1473 | | - foreach( $batch as $batchItem ) { |
| 1577 | + |
| 1578 | + foreach ( $batch as $batchItem ) { |
1474 | 1579 | list( $src, $dest ) = $batchItem; |
1475 | 1580 | $files[$src] = $this->file->repo->getVirtualUrl( 'public' ) . '/' . rawurlencode( $src ); |
1476 | 1581 | } |
| 1582 | + |
1477 | 1583 | $result = $this->file->repo->fileExistsBatch( $files, FSRepo::FILES_ONLY ); |
1478 | | - foreach( $batch as $batchItem ) |
1479 | | - if( $result[$batchItem[0]] ) |
| 1584 | + |
| 1585 | + foreach ( $batch as $batchItem ) { |
| 1586 | + if ( $result[$batchItem[0]] ) { |
1480 | 1587 | $newBatch[] = $batchItem; |
| 1588 | + } |
| 1589 | + } |
| 1590 | + |
1481 | 1591 | return $newBatch; |
1482 | 1592 | } |
1483 | 1593 | } |
1484 | 1594 | |
1485 | | -#------------------------------------------------------------------------------ |
| 1595 | +# ------------------------------------------------------------------------------ |
1486 | 1596 | |
1487 | 1597 | /** |
1488 | 1598 | * Helper class for file undeletion |
— | — | @@ -1527,6 +1637,7 @@ |
1528 | 1638 | */ |
1529 | 1639 | function execute() { |
1530 | 1640 | global $wgLang; |
| 1641 | + |
1531 | 1642 | if ( !$this->all && !$this->ids ) { |
1532 | 1643 | // Do nothing |
1533 | 1644 | return $this->file->repo->newGood(); |
— | — | @@ -1539,7 +1650,8 @@ |
1540 | 1651 | // Fetch all or selected archived revisions for the file, |
1541 | 1652 | // sorted from the most recent to the oldest. |
1542 | 1653 | $conditions = array( 'fa_name' => $this->file->getName() ); |
1543 | | - if( !$this->all ) { |
| 1654 | + |
| 1655 | + if ( !$this->all ) { |
1544 | 1656 | $conditions[] = 'fa_id IN (' . $dbw->makeList( $this->ids ) . ')'; |
1545 | 1657 | } |
1546 | 1658 | |
— | — | @@ -1556,7 +1668,8 @@ |
1557 | 1669 | $deleteIds = array(); |
1558 | 1670 | $first = true; |
1559 | 1671 | $archiveNames = array(); |
1560 | | - while( $row = $dbw->fetchObject( $result ) ) { |
| 1672 | + |
| 1673 | + while ( $row = $dbw->fetchObject( $result ) ) { |
1561 | 1674 | $idsPresent[] = $row->fa_id; |
1562 | 1675 | |
1563 | 1676 | if ( $row->fa_name != $this->file->getName() ) { |
— | — | @@ -1564,6 +1677,7 @@ |
1565 | 1678 | $status->failCount++; |
1566 | 1679 | continue; |
1567 | 1680 | } |
| 1681 | + |
1568 | 1682 | if ( $row->fa_storage_key == '' ) { |
1569 | 1683 | // Revision was missing pre-deletion |
1570 | 1684 | $status->error( 'undelete-bad-store-key', $wgLang->timeanddate( $row->fa_timestamp ) ); |
— | — | @@ -1575,12 +1689,13 @@ |
1576 | 1690 | $deletedUrl = $this->file->repo->getVirtualUrl() . '/deleted/' . $deletedRel; |
1577 | 1691 | |
1578 | 1692 | $sha1 = substr( $row->fa_storage_key, 0, strcspn( $row->fa_storage_key, '.' ) ); |
| 1693 | + |
1579 | 1694 | # Fix leading zero |
1580 | 1695 | if ( strlen( $sha1 ) == 32 && $sha1[0] == '0' ) { |
1581 | 1696 | $sha1 = substr( $sha1, 1 ); |
1582 | 1697 | } |
1583 | 1698 | |
1584 | | - if( is_null( $row->fa_major_mime ) || $row->fa_major_mime == 'unknown' |
| 1699 | + if ( is_null( $row->fa_major_mime ) || $row->fa_major_mime == 'unknown' |
1585 | 1700 | || is_null( $row->fa_minor_mime ) || $row->fa_minor_mime == 'unknown' |
1586 | 1701 | || is_null( $row->fa_media_type ) || $row->fa_media_type == 'UNKNOWN' |
1587 | 1702 | || is_null( $row->fa_metadata ) ) { |
— | — | @@ -1615,23 +1730,27 @@ |
1616 | 1731 | 'img_timestamp' => $row->fa_timestamp, |
1617 | 1732 | 'img_sha1' => $sha1 |
1618 | 1733 | ); |
| 1734 | + |
1619 | 1735 | // The live (current) version cannot be hidden! |
1620 | | - if( !$this->unsuppress && $row->fa_deleted ) { |
| 1736 | + if ( !$this->unsuppress && $row->fa_deleted ) { |
1621 | 1737 | $storeBatch[] = array( $deletedUrl, 'public', $destRel ); |
1622 | 1738 | $this->cleanupBatch[] = $row->fa_storage_key; |
1623 | 1739 | } |
1624 | 1740 | } else { |
1625 | 1741 | $archiveName = $row->fa_archive_name; |
1626 | | - if( $archiveName == '' ) { |
| 1742 | + |
| 1743 | + if ( $archiveName == '' ) { |
1627 | 1744 | // This was originally a current version; we |
1628 | 1745 | // have to devise a new archive name for it. |
1629 | 1746 | // Format is <timestamp of archiving>!<name> |
1630 | 1747 | $timestamp = wfTimestamp( TS_UNIX, $row->fa_deleted_timestamp ); |
| 1748 | + |
1631 | 1749 | do { |
1632 | 1750 | $archiveName = wfTimestamp( TS_MW, $timestamp ) . '!' . $row->fa_name; |
1633 | 1751 | $timestamp++; |
1634 | 1752 | } while ( isset( $archiveNames[$archiveName] ) ); |
1635 | 1753 | } |
| 1754 | + |
1636 | 1755 | $archiveNames[$archiveName] = true; |
1637 | 1756 | $destRel = $this->file->getArchiveRel( $archiveName ); |
1638 | 1757 | $insertBatch[] = array( |
— | — | @@ -1654,19 +1773,23 @@ |
1655 | 1774 | } |
1656 | 1775 | |
1657 | 1776 | $deleteIds[] = $row->fa_id; |
1658 | | - if( !$this->unsuppress && $row->fa_deleted & File::DELETED_FILE ) { |
| 1777 | + |
| 1778 | + if ( !$this->unsuppress && $row->fa_deleted & File::DELETED_FILE ) { |
1659 | 1779 | // private files can stay where they are |
1660 | 1780 | $status->successCount++; |
1661 | 1781 | } else { |
1662 | 1782 | $storeBatch[] = array( $deletedUrl, 'public', $destRel ); |
1663 | 1783 | $this->cleanupBatch[] = $row->fa_storage_key; |
1664 | 1784 | } |
| 1785 | + |
1665 | 1786 | $first = false; |
1666 | 1787 | } |
| 1788 | + |
1667 | 1789 | unset( $result ); |
1668 | 1790 | |
1669 | 1791 | // Add a warning to the status object for missing IDs |
1670 | 1792 | $missingIds = array_diff( $this->ids, $idsPresent ); |
| 1793 | + |
1671 | 1794 | foreach ( $missingIds as $id ) { |
1672 | 1795 | $status->error( 'undelete-missing-filearchive', $id ); |
1673 | 1796 | } |
— | — | @@ -1683,6 +1806,7 @@ |
1684 | 1807 | // Store batch returned a critical error -- this usually means nothing was stored |
1685 | 1808 | // Stop now and return an error |
1686 | 1809 | $this->file->unlock(); |
| 1810 | + |
1687 | 1811 | return $status; |
1688 | 1812 | } |
1689 | 1813 | |
— | — | @@ -1695,9 +1819,11 @@ |
1696 | 1820 | if ( $insertCurrent ) { |
1697 | 1821 | $dbw->insert( 'image', $insertCurrent, __METHOD__ ); |
1698 | 1822 | } |
| 1823 | + |
1699 | 1824 | if ( $insertBatch ) { |
1700 | 1825 | $dbw->insert( 'oldimage', $insertBatch, __METHOD__ ); |
1701 | 1826 | } |
| 1827 | + |
1702 | 1828 | if ( $deleteIds ) { |
1703 | 1829 | $dbw->delete( 'filearchive', |
1704 | 1830 | array( 'fa_id IN (' . $dbw->makeList( $deleteIds ) . ')' ), |
— | — | @@ -1705,8 +1831,8 @@ |
1706 | 1832 | } |
1707 | 1833 | |
1708 | 1834 | // If store batch is empty (all files are missing), deletion is to be considered successful |
1709 | | - if( $status->successCount > 0 || !$storeBatch ) { |
1710 | | - if( !$exists ) { |
| 1835 | + if ( $status->successCount > 0 || !$storeBatch ) { |
| 1836 | + if ( !$exists ) { |
1711 | 1837 | wfDebug( __METHOD__ . " restored {$status->successCount} items, creating a new current\n" ); |
1712 | 1838 | |
1713 | 1839 | // Update site_stats |
— | — | @@ -1720,7 +1846,9 @@ |
1721 | 1847 | $this->file->purgeHistory(); |
1722 | 1848 | } |
1723 | 1849 | } |
| 1850 | + |
1724 | 1851 | $this->file->unlock(); |
| 1852 | + |
1725 | 1853 | return $status; |
1726 | 1854 | } |
1727 | 1855 | |
— | — | @@ -1729,12 +1857,17 @@ |
1730 | 1858 | */ |
1731 | 1859 | function removeNonexistentFiles( $triplets ) { |
1732 | 1860 | $files = $filteredTriplets = array(); |
1733 | | - foreach( $triplets as $file ) |
| 1861 | + foreach ( $triplets as $file ) |
1734 | 1862 | $files[$file[0]] = $file[0]; |
| 1863 | + |
1735 | 1864 | $result = $this->file->repo->fileExistsBatch( $files, FSRepo::FILES_ONLY ); |
1736 | | - foreach( $triplets as $file ) |
1737 | | - if( $result[$file[0]] ) |
| 1865 | + |
| 1866 | + foreach ( $triplets as $file ) { |
| 1867 | + if ( $result[$file[0]] ) { |
1738 | 1868 | $filteredTriplets[] = $file; |
| 1869 | + } |
| 1870 | + } |
| 1871 | + |
1739 | 1872 | return $filteredTriplets; |
1740 | 1873 | } |
1741 | 1874 | |
— | — | @@ -1744,15 +1877,20 @@ |
1745 | 1878 | function removeNonexistentFromCleanup( $batch ) { |
1746 | 1879 | $files = $newBatch = array(); |
1747 | 1880 | $repo = $this->file->repo; |
1748 | | - foreach( $batch as $file ) { |
| 1881 | + |
| 1882 | + foreach ( $batch as $file ) { |
1749 | 1883 | $files[$file] = $repo->getVirtualUrl( 'deleted' ) . '/' . |
1750 | 1884 | rawurlencode( $repo->getDeletedHashPath( $file ) . $file ); |
1751 | 1885 | } |
1752 | 1886 | |
1753 | 1887 | $result = $repo->fileExistsBatch( $files, FSRepo::FILES_ONLY ); |
1754 | | - foreach( $batch as $file ) |
1755 | | - if( $result[$file] ) |
| 1888 | + |
| 1889 | + foreach ( $batch as $file ) { |
| 1890 | + if ( $result[$file] ) { |
1756 | 1891 | $newBatch[] = $file; |
| 1892 | + } |
| 1893 | + } |
| 1894 | + |
1757 | 1895 | return $newBatch; |
1758 | 1896 | } |
1759 | 1897 | |
— | — | @@ -1764,13 +1902,16 @@ |
1765 | 1903 | if ( !$this->cleanupBatch ) { |
1766 | 1904 | return $this->file->repo->newGood(); |
1767 | 1905 | } |
| 1906 | + |
1768 | 1907 | $this->cleanupBatch = $this->removeNonexistentFromCleanup( $this->cleanupBatch ); |
| 1908 | + |
1769 | 1909 | $status = $this->file->repo->cleanupDeletedBatch( $this->cleanupBatch ); |
| 1910 | + |
1770 | 1911 | return $status; |
1771 | 1912 | } |
1772 | 1913 | } |
1773 | 1914 | |
1774 | | -#------------------------------------------------------------------------------ |
| 1915 | +# ------------------------------------------------------------------------------ |
1775 | 1916 | |
1776 | 1917 | /** |
1777 | 1918 | * Helper class for file movement |
— | — | @@ -1811,23 +1952,30 @@ |
1812 | 1953 | array( 'oi_name' => $this->oldName ), |
1813 | 1954 | __METHOD__ |
1814 | 1955 | ); |
1815 | | - while( $row = $this->db->fetchObject( $result ) ) { |
| 1956 | + |
| 1957 | + while ( $row = $this->db->fetchObject( $result ) ) { |
1816 | 1958 | $oldName = $row->oi_archive_name; |
1817 | 1959 | $bits = explode( '!', $oldName, 2 ); |
1818 | | - if( count( $bits ) != 2 ) { |
| 1960 | + |
| 1961 | + if ( count( $bits ) != 2 ) { |
1819 | 1962 | wfDebug( "Invalid old file name: $oldName \n" ); |
1820 | 1963 | continue; |
1821 | 1964 | } |
| 1965 | + |
1822 | 1966 | list( $timestamp, $filename ) = $bits; |
1823 | | - if( $this->oldName != $filename ) { |
| 1967 | + |
| 1968 | + if ( $this->oldName != $filename ) { |
1824 | 1969 | wfDebug( "Invalid old file name: $oldName \n" ); |
1825 | 1970 | continue; |
1826 | 1971 | } |
| 1972 | + |
1827 | 1973 | $this->oldCount++; |
| 1974 | + |
1828 | 1975 | // Do we want to add those to oldCount? |
1829 | | - if( $row->oi_deleted & File::DELETED_FILE ) { |
| 1976 | + if ( $row->oi_deleted & File::DELETED_FILE ) { |
1830 | 1977 | continue; |
1831 | 1978 | } |
| 1979 | + |
1832 | 1980 | $this->olds[] = array( |
1833 | 1981 | "{$archiveBase}/{$this->oldHash}{$oldName}", |
1834 | 1982 | "{$archiveBase}/{$this->newHash}{$timestamp}!{$this->newName}" |
— | — | @@ -1848,13 +1996,15 @@ |
1849 | 1997 | wfDebugLog( 'imagemove', "Renamed {$this->file->name} in database: {$statusDb->successCount} successes, {$statusDb->failCount} failures" ); |
1850 | 1998 | $statusMove = $repo->storeBatch( $triplets, FSRepo::DELETE_SOURCE ); |
1851 | 1999 | wfDebugLog( 'imagemove', "Moved files for {$this->file->name}: {$statusMove->successCount} successes, {$statusMove->failCount} failures" ); |
1852 | | - if( !$statusMove->isOk() ) { |
| 2000 | + |
| 2001 | + if ( !$statusMove->isOk() ) { |
1853 | 2002 | wfDebugLog( 'imagemove', "Error in moving files: " . $statusMove->getWikiText() ); |
1854 | 2003 | $this->db->rollback(); |
1855 | 2004 | } |
1856 | 2005 | |
1857 | 2006 | $status->merge( $statusDb ); |
1858 | 2007 | $status->merge( $statusMove ); |
| 2008 | + |
1859 | 2009 | return $status; |
1860 | 2010 | } |
1861 | 2011 | |
— | — | @@ -1876,7 +2026,8 @@ |
1877 | 2027 | array( 'img_name' => $this->oldName ), |
1878 | 2028 | __METHOD__ |
1879 | 2029 | ); |
1880 | | - if( $dbw->affectedRows() ) { |
| 2030 | + |
| 2031 | + if ( $dbw->affectedRows() ) { |
1881 | 2032 | $status->successCount++; |
1882 | 2033 | } else { |
1883 | 2034 | $status->failCount++; |
— | — | @@ -1887,11 +2038,12 @@ |
1888 | 2039 | 'oldimage', |
1889 | 2040 | array( |
1890 | 2041 | 'oi_name' => $this->newName, |
1891 | | - 'oi_archive_name = ' . $dbw->strreplace( 'oi_archive_name', $dbw->addQuotes($this->oldName), $dbw->addQuotes($this->newName) ), |
| 2042 | + 'oi_archive_name = ' . $dbw->strreplace( 'oi_archive_name', $dbw->addQuotes( $this->oldName ), $dbw->addQuotes( $this->newName ) ), |
1892 | 2043 | ), |
1893 | 2044 | array( 'oi_name' => $this->oldName ), |
1894 | 2045 | __METHOD__ |
1895 | 2046 | ); |
| 2047 | + |
1896 | 2048 | $affected = $dbw->affectedRows(); |
1897 | 2049 | $total = $this->oldCount; |
1898 | 2050 | $status->successCount += $affected; |
— | — | @@ -1906,12 +2058,14 @@ |
1907 | 2059 | function getMoveTriplets() { |
1908 | 2060 | $moves = array_merge( array( $this->cur ), $this->olds ); |
1909 | 2061 | $triplets = array(); // The format is: (srcUrl, destZone, destUrl) |
1910 | | - foreach( $moves as $move ) { |
| 2062 | + |
| 2063 | + foreach ( $moves as $move ) { |
1911 | 2064 | // $move: (oldRelativePath, newRelativePath) |
1912 | 2065 | $srcUrl = $this->file->repo->getVirtualUrl() . '/public/' . rawurlencode( $move[0] ); |
1913 | 2066 | $triplets[] = array( $srcUrl, 'public', $move[1] ); |
1914 | 2067 | wfDebugLog( 'imagemove', "Generated move triplet for {$this->file->name}: {$srcUrl} :: public :: {$move[1]}" ); |
1915 | 2068 | } |
| 2069 | + |
1916 | 2070 | return $triplets; |
1917 | 2071 | } |
1918 | 2072 | |
— | — | @@ -1920,16 +2074,22 @@ |
1921 | 2075 | */ |
1922 | 2076 | function removeNonexistentFiles( $triplets ) { |
1923 | 2077 | $files = array(); |
1924 | | - foreach( $triplets as $file ) |
| 2078 | + |
| 2079 | + foreach ( $triplets as $file ) { |
1925 | 2080 | $files[$file[0]] = $file[0]; |
| 2081 | + } |
| 2082 | + |
1926 | 2083 | $result = $this->file->repo->fileExistsBatch( $files, FSRepo::FILES_ONLY ); |
1927 | 2084 | $filteredTriplets = array(); |
1928 | | - foreach( $triplets as $file ) |
1929 | | - if( $result[$file[0]] ) { |
| 2085 | + |
| 2086 | + foreach ( $triplets as $file ) { |
| 2087 | + if ( $result[$file[0]] ) { |
1930 | 2088 | $filteredTriplets[] = $file; |
1931 | 2089 | } else { |
1932 | 2090 | wfDebugLog( 'imagemove', "File {$file[0]} does not exist" ); |
1933 | 2091 | } |
| 2092 | + } |
| 2093 | + |
1934 | 2094 | return $filteredTriplets; |
1935 | 2095 | } |
1936 | 2096 | } |
Index: trunk/phase3/includes/installer/CliInstaller.php |
— | — | @@ -101,14 +101,14 @@ |
102 | 102 | $this->showStatusMessage( $status ); |
103 | 103 | echo "\n"; |
104 | 104 | exit; |
105 | | - } elseif ( count($warnings) !== 0 ) { |
| 105 | + } elseif ( count( $warnings ) !== 0 ) { |
106 | 106 | foreach ( $status->getWikiTextArray( $warnings ) as $w ) { |
107 | 107 | $this->showMessage( $w . wfMsg( 'ellipsis' ) . |
108 | 108 | wfMsg( 'word-separator' ) ); |
109 | 109 | } |
110 | 110 | } |
111 | 111 | |
112 | | - $this->showMessage( wfMsg( 'config-install-step-done' ) ."\n"); |
| 112 | + $this->showMessage( wfMsg( 'config-install-step-done' ) . "\n" ); |
113 | 113 | } |
114 | 114 | |
115 | 115 | public function showMessage( $msg /*, ... */ ) { |
— | — | @@ -119,5 +119,4 @@ |
120 | 120 | public function showStatusMessage( Status $status ) { |
121 | 121 | $this->showMessage( $status->getWikiText() ); |
122 | 122 | } |
123 | | - |
124 | | -} |
\ No newline at end of file |
| 123 | +} |
Index: trunk/phase3/includes/HttpFunctions.php |
— | — | @@ -35,11 +35,14 @@ |
36 | 36 | $url = wfExpandUrl( $url ); |
37 | 37 | wfDebug( "HTTP: $method: $url\n" ); |
38 | 38 | $options['method'] = strtoupper( $method ); |
| 39 | + |
39 | 40 | if ( !isset( $options['timeout'] ) ) { |
40 | 41 | $options['timeout'] = 'default'; |
41 | 42 | } |
| 43 | + |
42 | 44 | $req = HttpRequest::factory( $url, $options ); |
43 | 45 | $status = $req->execute(); |
| 46 | + |
44 | 47 | if ( $status->isOK() ) { |
45 | 48 | return $req->getContent(); |
46 | 49 | } else { |
— | — | @@ -72,6 +75,7 @@ |
73 | 76 | */ |
74 | 77 | public static function isLocalURL( $url ) { |
75 | 78 | global $wgCommandLineMode, $wgConf; |
| 79 | + |
76 | 80 | if ( $wgCommandLineMode ) { |
77 | 81 | return false; |
78 | 82 | } |
— | — | @@ -84,6 +88,7 @@ |
85 | 89 | $domainParts = explode( '.', $host ); |
86 | 90 | // Check if this domain or any superdomain is listed in $wgConf as a local virtual host |
87 | 91 | $domainParts = array_reverse( $domainParts ); |
| 92 | + |
88 | 93 | for ( $i = 0; $i < count( $domainParts ); $i++ ) { |
89 | 94 | $domainPart = $domainParts[$i]; |
90 | 95 | if ( $i == 0 ) { |
— | — | @@ -91,11 +96,13 @@ |
92 | 97 | } else { |
93 | 98 | $domain = $domainPart . '.' . $domain; |
94 | 99 | } |
| 100 | + |
95 | 101 | if ( $wgConf->isLocalVHost( $domain ) ) { |
96 | 102 | return true; |
97 | 103 | } |
98 | 104 | } |
99 | 105 | } |
| 106 | + |
100 | 107 | return false; |
101 | 108 | } |
102 | 109 | |
— | — | @@ -165,12 +172,12 @@ |
166 | 173 | $this->parsedUrl = parse_url( $url ); |
167 | 174 | |
168 | 175 | if ( !Http::isValidURI( $this->url ) ) { |
169 | | - $this->status = Status::newFatal('http-invalid-url'); |
| 176 | + $this->status = Status::newFatal( 'http-invalid-url' ); |
170 | 177 | } else { |
171 | 178 | $this->status = Status::newGood( 100 ); // continue |
172 | 179 | } |
173 | 180 | |
174 | | - if ( isset($options['timeout']) && $options['timeout'] != 'default' ) { |
| 181 | + if ( isset( $options['timeout'] ) && $options['timeout'] != 'default' ) { |
175 | 182 | $this->timeout = $options['timeout']; |
176 | 183 | } else { |
177 | 184 | $this->timeout = $wgHTTPTimeout; |
— | — | @@ -178,8 +185,9 @@ |
179 | 186 | |
180 | 187 | $members = array( "postData", "proxy", "noProxy", "sslVerifyHost", "caInfo", |
181 | 188 | "method", "followRedirects", "maxRedirects", "sslVerifyCert" ); |
| 189 | + |
182 | 190 | foreach ( $members as $o ) { |
183 | | - if ( isset($options[$o]) ) { |
| 191 | + if ( isset( $options[$o] ) ) { |
184 | 192 | $this->$o = $options[$o]; |
185 | 193 | } |
186 | 194 | } |
— | — | @@ -193,21 +201,21 @@ |
194 | 202 | if ( !Http::$httpEngine ) { |
195 | 203 | Http::$httpEngine = function_exists( 'curl_init' ) ? 'curl' : 'php'; |
196 | 204 | } elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) { |
197 | | - throw new MWException( __METHOD__.': curl (http://php.net/curl) is not installed, but'. |
| 205 | + throw new MWException( __METHOD__ . ': curl (http://php.net/curl) is not installed, but' . |
198 | 206 | ' Http::$httpEngine is set to "curl"' ); |
199 | 207 | } |
200 | 208 | |
201 | 209 | switch( Http::$httpEngine ) { |
202 | | - case 'curl': |
203 | | - return new CurlHttpRequest( $url, $options ); |
204 | | - case 'php': |
205 | | - if ( !wfIniGetBool( 'allow_url_fopen' ) ) { |
206 | | - throw new MWException( __METHOD__.': allow_url_fopen needs to be enabled for pure PHP'. |
207 | | - ' http requests to work. If possible, curl should be used instead. See http://php.net/curl.' ); |
208 | | - } |
209 | | - return new PhpHttpRequest( $url, $options ); |
210 | | - default: |
211 | | - throw new MWException( __METHOD__.': The setting of Http::$httpEngine is not valid.' ); |
| 210 | + case 'curl': |
| 211 | + return new CurlHttpRequest( $url, $options ); |
| 212 | + case 'php': |
| 213 | + if ( !wfIniGetBool( 'allow_url_fopen' ) ) { |
| 214 | + throw new MWException( __METHOD__ . ': allow_url_fopen needs to be enabled for pure PHP' . |
| 215 | + ' http requests to work. If possible, curl should be used instead. See http://php.net/curl.' ); |
| 216 | + } |
| 217 | + return new PhpHttpRequest( $url, $options ); |
| 218 | + default: |
| 219 | + throw new MWException( __METHOD__ . ': The setting of Http::$httpEngine is not valid.' ); |
212 | 220 | } |
213 | 221 | } |
214 | 222 | |
— | — | @@ -226,7 +234,7 @@ |
227 | 235 | * @param $args Array |
228 | 236 | * @todo overload the args param |
229 | 237 | */ |
230 | | - public function setData($args) { |
| 238 | + public function setData( $args ) { |
231 | 239 | $this->postData = $args; |
232 | 240 | } |
233 | 241 | |
— | — | @@ -242,6 +250,7 @@ |
243 | 251 | if ( $this->proxy ) { |
244 | 252 | return; |
245 | 253 | } |
| 254 | + |
246 | 255 | if ( Http::isLocalURL( $this->url ) ) { |
247 | 256 | $this->proxy = 'http://localhost:80/'; |
248 | 257 | } elseif ( $wgHTTPProxy ) { |
— | — | @@ -255,20 +264,20 @@ |
256 | 265 | * Set the refererer header |
257 | 266 | */ |
258 | 267 | public function setReferer( $url ) { |
259 | | - $this->setHeader('Referer', $url); |
| 268 | + $this->setHeader( 'Referer', $url ); |
260 | 269 | } |
261 | 270 | |
262 | 271 | /** |
263 | 272 | * Set the user agent |
264 | 273 | */ |
265 | 274 | public function setUserAgent( $UA ) { |
266 | | - $this->setHeader('User-Agent', $UA); |
| 275 | + $this->setHeader( 'User-Agent', $UA ); |
267 | 276 | } |
268 | 277 | |
269 | 278 | /** |
270 | 279 | * Set an arbitrary header |
271 | 280 | */ |
272 | | - public function setHeader($name, $value) { |
| 281 | + public function setHeader( $name, $value ) { |
273 | 282 | // I feel like I should normalize the case here... |
274 | 283 | $this->reqHeaders[$name] = $value; |
275 | 284 | } |
— | — | @@ -279,14 +288,18 @@ |
280 | 289 | public function getHeaderList() { |
281 | 290 | $list = array(); |
282 | 291 | |
283 | | - if( $this->cookieJar ) { |
| 292 | + if ( $this->cookieJar ) { |
284 | 293 | $this->reqHeaders['Cookie'] = |
285 | | - $this->cookieJar->serializeToHttpRequest($this->parsedUrl['path'], |
286 | | - $this->parsedUrl['host']); |
| 294 | + $this->cookieJar->serializeToHttpRequest( |
| 295 | + $this->parsedUrl['path'], |
| 296 | + $this->parsedUrl['host'] |
| 297 | + ); |
287 | 298 | } |
288 | | - foreach($this->reqHeaders as $name => $value) { |
| 299 | + |
| 300 | + foreach ( $this->reqHeaders as $name => $value ) { |
289 | 301 | $list[] = "$name: $value"; |
290 | 302 | } |
| 303 | + |
291 | 304 | return $list; |
292 | 305 | } |
293 | 306 | |
— | — | @@ -321,7 +334,7 @@ |
322 | 335 | |
323 | 336 | $this->content = ""; |
324 | 337 | |
325 | | - if( strtoupper($this->method) == "HEAD" ) { |
| 338 | + if ( strtoupper( $this->method ) == "HEAD" ) { |
326 | 339 | $this->headersOnly = true; |
327 | 340 | } |
328 | 341 | |
— | — | @@ -329,7 +342,7 @@ |
330 | 343 | $this->postData = wfArrayToCGI( $this->postData ); |
331 | 344 | } |
332 | 345 | |
333 | | - if ( is_object( $wgTitle ) && !isset($this->reqHeaders['Referer']) ) { |
| 346 | + if ( is_object( $wgTitle ) && !isset( $this->reqHeaders['Referer'] ) ) { |
334 | 347 | $this->setReferer( $wgTitle->getFullURL() ); |
335 | 348 | } |
336 | 349 | |
— | — | @@ -341,8 +354,8 @@ |
342 | 355 | $this->setCallback( array( $this, 'read' ) ); |
343 | 356 | } |
344 | 357 | |
345 | | - if ( !isset($this->reqHeaders['User-Agent']) ) { |
346 | | - $this->setUserAgent(Http::userAgent()); |
| 358 | + if ( !isset( $this->reqHeaders['User-Agent'] ) ) { |
| 359 | + $this->setUserAgent( Http::userAgent() ); |
347 | 360 | } |
348 | 361 | } |
349 | 362 | |
— | — | @@ -355,14 +368,15 @@ |
356 | 369 | */ |
357 | 370 | protected function parseHeader() { |
358 | 371 | $lastname = ""; |
359 | | - foreach( $this->headerList as $header ) { |
360 | | - if( preg_match( "#^HTTP/([0-9.]+) (.*)#", $header, $match ) ) { |
| 372 | + |
| 373 | + foreach ( $this->headerList as $header ) { |
| 374 | + if ( preg_match( "#^HTTP/([0-9.]+) (.*)#", $header, $match ) ) { |
361 | 375 | $this->respVersion = $match[1]; |
362 | 376 | $this->respStatus = $match[2]; |
363 | | - } elseif( preg_match( "#^[ \t]#", $header ) ) { |
364 | | - $last = count($this->respHeaders[$lastname]) - 1; |
| 377 | + } elseif ( preg_match( "#^[ \t]#", $header ) ) { |
| 378 | + $last = count( $this->respHeaders[$lastname] ) - 1; |
365 | 379 | $this->respHeaders[$lastname][$last] .= "\r\n$header"; |
366 | | - } elseif( preg_match( "#^([^:]*):[\t ]*(.*)#", $header, $match ) ) { |
| 380 | + } elseif ( preg_match( "#^([^:]*):[\t ]*(.*)#", $header, $match ) ) { |
367 | 381 | $this->respHeaders[strtolower( $match[1] )][] = $match[2]; |
368 | 382 | $lastname = strtolower( $match[1] ); |
369 | 383 | } |
— | — | @@ -378,13 +392,13 @@ |
379 | 393 | * @return nothing |
380 | 394 | */ |
381 | 395 | protected function setStatus() { |
382 | | - if( !$this->respHeaders ) { |
| 396 | + if ( !$this->respHeaders ) { |
383 | 397 | $this->parseHeader(); |
384 | 398 | } |
385 | 399 | |
386 | | - if((int)$this->respStatus !== 200) { |
387 | | - list( $code, $message ) = explode(" ", $this->respStatus, 2); |
388 | | - $this->status->fatal("http-bad-status", $code, $message ); |
| 400 | + if ( (int)$this->respStatus !== 200 ) { |
| 401 | + list( $code, $message ) = explode( " ", $this->respStatus, 2 ); |
| 402 | + $this->status->fatal( "http-bad-status", $code, $message ); |
389 | 403 | } |
390 | 404 | } |
391 | 405 | |
— | — | @@ -395,14 +409,16 @@ |
396 | 410 | * @return Boolean |
397 | 411 | */ |
398 | 412 | public function isRedirect() { |
399 | | - if( !$this->respHeaders ) { |
| 413 | + if ( !$this->respHeaders ) { |
400 | 414 | $this->parseHeader(); |
401 | 415 | } |
402 | 416 | |
403 | 417 | $status = (int)$this->respStatus; |
| 418 | + |
404 | 419 | if ( $status >= 300 && $status <= 303 ) { |
405 | 420 | return true; |
406 | 421 | } |
| 422 | + |
407 | 423 | return false; |
408 | 424 | } |
409 | 425 | |
— | — | @@ -415,9 +431,10 @@ |
416 | 432 | * @return Array |
417 | 433 | */ |
418 | 434 | public function getResponseHeaders() { |
419 | | - if( !$this->respHeaders ) { |
| 435 | + if ( !$this->respHeaders ) { |
420 | 436 | $this->parseHeader(); |
421 | 437 | } |
| 438 | + |
422 | 439 | return $this->respHeaders; |
423 | 440 | } |
424 | 441 | |
— | — | @@ -427,14 +444,16 @@ |
428 | 445 | * @param $header String |
429 | 446 | * @return String |
430 | 447 | */ |
431 | | - public function getResponseHeader($header) { |
432 | | - if( !$this->respHeaders ) { |
| 448 | + public function getResponseHeader( $header ) { |
| 449 | + if ( !$this->respHeaders ) { |
433 | 450 | $this->parseHeader(); |
434 | 451 | } |
| 452 | + |
435 | 453 | if ( isset( $this->respHeaders[strtolower ( $header ) ] ) ) { |
436 | 454 | $v = $this->respHeaders[strtolower ( $header ) ]; |
437 | 455 | return $v[count( $v ) - 1]; |
438 | 456 | } |
| 457 | + |
439 | 458 | return null; |
440 | 459 | } |
441 | 460 | |
— | — | @@ -453,9 +472,10 @@ |
454 | 473 | * @returns CookieJar |
455 | 474 | */ |
456 | 475 | public function getCookieJar() { |
457 | | - if( !$this->respHeaders ) { |
| 476 | + if ( !$this->respHeaders ) { |
458 | 477 | $this->parseHeader(); |
459 | 478 | } |
| 479 | + |
460 | 480 | return $this->cookieJar; |
461 | 481 | } |
462 | 482 | |
— | — | @@ -465,23 +485,25 @@ |
466 | 486 | * Set-Cookie headers. |
467 | 487 | * @see Cookie::set |
468 | 488 | */ |
469 | | - public function setCookie( $name, $value = null, $attr = null) { |
470 | | - if( !$this->cookieJar ) { |
| 489 | + public function setCookie( $name, $value = null, $attr = null ) { |
| 490 | + if ( !$this->cookieJar ) { |
471 | 491 | $this->cookieJar = new CookieJar; |
472 | 492 | } |
473 | | - $this->cookieJar->setCookie($name, $value, $attr); |
| 493 | + |
| 494 | + $this->cookieJar->setCookie( $name, $value, $attr ); |
474 | 495 | } |
475 | 496 | |
476 | 497 | /** |
477 | 498 | * Parse the cookies in the response headers and store them in the cookie jar. |
478 | 499 | */ |
479 | 500 | protected function parseCookies() { |
480 | | - if( !$this->cookieJar ) { |
| 501 | + if ( !$this->cookieJar ) { |
481 | 502 | $this->cookieJar = new CookieJar; |
482 | 503 | } |
483 | | - if( isset( $this->respHeaders['set-cookie'] ) ) { |
| 504 | + |
| 505 | + if ( isset( $this->respHeaders['set-cookie'] ) ) { |
484 | 506 | $url = parse_url( $this->getFinalUrl() ); |
485 | | - foreach( $this->respHeaders['set-cookie'] as $cookie ) { |
| 507 | + foreach ( $this->respHeaders['set-cookie'] as $cookie ) { |
486 | 508 | $this->cookieJar->parseCookieResponseHeader( $cookie, $url['host'] ); |
487 | 509 | } |
488 | 510 | } |
— | — | @@ -493,7 +515,8 @@ |
494 | 516 | * @return String |
495 | 517 | */ |
496 | 518 | public function getFinalUrl() { |
497 | | - $location = $this->getResponseHeader("Location"); |
| 519 | + $location = $this->getResponseHeader( "Location" ); |
| 520 | + |
498 | 521 | if ( $location ) { |
499 | 522 | return $location; |
500 | 523 | } |
— | — | @@ -541,21 +564,24 @@ |
542 | 565 | */ |
543 | 566 | public function set( $value, $attr ) { |
544 | 567 | $this->value = $value; |
545 | | - if( isset( $attr['expires'] ) ) { |
| 568 | + |
| 569 | + if ( isset( $attr['expires'] ) ) { |
546 | 570 | $this->isSessionKey = false; |
547 | 571 | $this->expires = strtotime( $attr['expires'] ); |
548 | 572 | } |
549 | | - if( isset( $attr['path'] ) ) { |
| 573 | + |
| 574 | + if ( isset( $attr['path'] ) ) { |
550 | 575 | $this->path = $attr['path']; |
551 | 576 | } else { |
552 | 577 | $this->path = "/"; |
553 | 578 | } |
554 | | - if( isset( $attr['domain'] ) ) { |
555 | | - if( self::validateCookieDomain( $attr['domain'] ) ) { |
| 579 | + |
| 580 | + if ( isset( $attr['domain'] ) ) { |
| 581 | + if ( self::validateCookieDomain( $attr['domain'] ) ) { |
556 | 582 | $this->domain = $attr['domain']; |
557 | 583 | } |
558 | 584 | } else { |
559 | | - throw new MWException("You must specify a domain."); |
| 585 | + throw new MWException( "You must specify a domain." ); |
560 | 586 | } |
561 | 587 | } |
562 | 588 | |
— | — | @@ -571,39 +597,48 @@ |
572 | 598 | * @param $originDomain String: (optional) the domain the cookie originates from |
573 | 599 | * @return Boolean |
574 | 600 | */ |
575 | | - public static function validateCookieDomain( $domain, $originDomain = null) { |
| 601 | + public static function validateCookieDomain( $domain, $originDomain = null ) { |
576 | 602 | // Don't allow a trailing dot |
577 | | - if( substr( $domain, -1 ) == "." ) return false; |
| 603 | + if ( substr( $domain, -1 ) == "." ) { |
| 604 | + return false; |
| 605 | + } |
578 | 606 | |
579 | | - $dc = explode(".", $domain); |
| 607 | + $dc = explode( ".", $domain ); |
580 | 608 | |
581 | 609 | // Only allow full, valid IP addresses |
582 | | - if( preg_match( '/^[0-9.]+$/', $domain ) ) { |
583 | | - if( count( $dc ) != 4 ) return false; |
| 610 | + if ( preg_match( '/^[0-9.]+$/', $domain ) ) { |
| 611 | + if ( count( $dc ) != 4 ) { |
| 612 | + return false; |
| 613 | + } |
584 | 614 | |
585 | | - if( ip2long( $domain ) === false ) return false; |
| 615 | + if ( ip2long( $domain ) === false ) { |
| 616 | + return false; |
| 617 | + } |
586 | 618 | |
587 | | - if( $originDomain == null || $originDomain == $domain ) return true; |
| 619 | + if ( $originDomain == null || $originDomain == $domain ) { |
| 620 | + return true; |
| 621 | + } |
588 | 622 | |
589 | 623 | } |
590 | 624 | |
591 | 625 | // Don't allow cookies for "co.uk" or "gov.uk", etc, but allow "supermarket.uk" |
592 | | - if( strrpos( $domain, "." ) - strlen( $domain ) == -3 ) { |
593 | | - if( (count($dc) == 2 && strlen( $dc[0] ) <= 2 ) |
594 | | - || (count($dc) == 3 && strlen( $dc[0] ) == "" && strlen( $dc[1] ) <= 2 ) ) { |
| 626 | + if ( strrpos( $domain, "." ) - strlen( $domain ) == -3 ) { |
| 627 | + if ( ( count( $dc ) == 2 && strlen( $dc[0] ) <= 2 ) |
| 628 | + || ( count( $dc ) == 3 && strlen( $dc[0] ) == "" && strlen( $dc[1] ) <= 2 ) ) { |
595 | 629 | return false; |
596 | 630 | } |
597 | | - if( (count($dc) == 2 || (count($dc) == 3 && $dc[0] == "") ) |
598 | | - && preg_match( '/(com|net|org|gov|edu)\...$/', $domain) ) { |
| 631 | + if ( ( count( $dc ) == 2 || ( count( $dc ) == 3 && $dc[0] == "" ) ) |
| 632 | + && preg_match( '/(com|net|org|gov|edu)\...$/', $domain ) ) { |
599 | 633 | return false; |
600 | 634 | } |
601 | 635 | } |
602 | 636 | |
603 | | - if( $originDomain != null ) { |
604 | | - if( substr( $domain, 0, 1 ) != "." && $domain != $originDomain ) { |
| 637 | + if ( $originDomain != null ) { |
| 638 | + if ( substr( $domain, 0, 1 ) != "." && $domain != $originDomain ) { |
605 | 639 | return false; |
606 | 640 | } |
607 | | - if( substr( $domain, 0, 1 ) == "." |
| 641 | + |
| 642 | + if ( substr( $domain, 0, 1 ) == "." |
608 | 643 | && substr_compare( $originDomain, $domain, -strlen( $domain ), |
609 | 644 | strlen( $domain ), TRUE ) != 0 ) { |
610 | 645 | return false; |
— | — | @@ -623,40 +658,42 @@ |
624 | 659 | public function serializeToHttpRequest( $path, $domain ) { |
625 | 660 | $ret = ""; |
626 | 661 | |
627 | | - if( $this->canServeDomain( $domain ) |
| 662 | + if ( $this->canServeDomain( $domain ) |
628 | 663 | && $this->canServePath( $path ) |
629 | 664 | && $this->isUnExpired() ) { |
630 | | - $ret = $this->name ."=". $this->value; |
| 665 | + $ret = $this->name . "=" . $this->value; |
631 | 666 | } |
632 | 667 | |
633 | 668 | return $ret; |
634 | 669 | } |
635 | 670 | |
636 | 671 | protected function canServeDomain( $domain ) { |
637 | | - if( $domain == $this->domain |
638 | | - || ( strlen( $domain) > strlen( $this->domain ) |
639 | | - && substr( $this->domain, 0, 1) == "." |
| 672 | + if ( $domain == $this->domain |
| 673 | + || ( strlen( $domain ) > strlen( $this->domain ) |
| 674 | + && substr( $this->domain, 0, 1 ) == "." |
640 | 675 | && substr_compare( $domain, $this->domain, -strlen( $this->domain ), |
641 | 676 | strlen( $this->domain ), TRUE ) == 0 ) ) { |
642 | 677 | return true; |
643 | 678 | } |
| 679 | + |
644 | 680 | return false; |
645 | 681 | } |
646 | 682 | |
647 | 683 | protected function canServePath( $path ) { |
648 | | - if( $this->path && substr_compare( $this->path, $path, 0, strlen( $this->path ) ) == 0 ) { |
| 684 | + if ( $this->path && substr_compare( $this->path, $path, 0, strlen( $this->path ) ) == 0 ) { |
649 | 685 | return true; |
650 | 686 | } |
| 687 | + |
651 | 688 | return false; |
652 | 689 | } |
653 | 690 | |
654 | 691 | protected function isUnExpired() { |
655 | | - if( $this->isSessionKey || $this->expires > time() ) { |
| 692 | + if ( $this->isSessionKey || $this->expires > time() ) { |
656 | 693 | return true; |
657 | 694 | } |
| 695 | + |
658 | 696 | return false; |
659 | 697 | } |
660 | | - |
661 | 698 | } |
662 | 699 | |
663 | 700 | class CookieJar { |
— | — | @@ -666,12 +703,13 @@ |
667 | 704 | * Set a cookie in the cookie jar. Make sure only one cookie per-name exists. |
668 | 705 | * @see Cookie::set() |
669 | 706 | */ |
670 | | - public function setCookie ($name, $value, $attr) { |
| 707 | + public function setCookie ( $name, $value, $attr ) { |
671 | 708 | /* cookies: case insensitive, so this should work. |
672 | 709 | * We'll still send the cookies back in the same case we got them, though. |
673 | 710 | */ |
674 | | - $index = strtoupper($name); |
675 | | - if( isset( $this->cookie[$index] ) ) { |
| 711 | + $index = strtoupper( $name ); |
| 712 | + |
| 713 | + if ( isset( $this->cookie[$index] ) ) { |
676 | 714 | $this->cookie[$index]->set( $value, $attr ); |
677 | 715 | } else { |
678 | 716 | $this->cookie[$index] = new Cookie( $name, $value, $attr ); |
— | — | @@ -684,12 +722,15 @@ |
685 | 723 | public function serializeToHttpRequest( $path, $domain ) { |
686 | 724 | $cookies = array(); |
687 | 725 | |
688 | | - foreach( $this->cookie as $c ) { |
| 726 | + foreach ( $this->cookie as $c ) { |
689 | 727 | $serialized = $c->serializeToHttpRequest( $path, $domain ); |
690 | | - if ( $serialized ) $cookies[] = $serialized; |
| 728 | + |
| 729 | + if ( $serialized ) { |
| 730 | + $cookies[] = $serialized; |
| 731 | + } |
691 | 732 | } |
692 | 733 | |
693 | | - return implode("; ", $cookies); |
| 734 | + return implode( "; ", $cookies ); |
694 | 735 | } |
695 | 736 | |
696 | 737 | /** |
— | — | @@ -700,34 +741,37 @@ |
701 | 742 | */ |
702 | 743 | public function parseCookieResponseHeader ( $cookie, $domain ) { |
703 | 744 | $len = strlen( "Set-Cookie:" ); |
| 745 | + |
704 | 746 | if ( substr_compare( "Set-Cookie:", $cookie, 0, $len, TRUE ) === 0 ) { |
705 | 747 | $cookie = substr( $cookie, $len ); |
706 | 748 | } |
707 | 749 | |
708 | 750 | $bit = array_map( 'trim', explode( ";", $cookie ) ); |
709 | | - if ( count($bit) >= 1 ) { |
710 | | - list($name, $value) = explode( "=", array_shift( $bit ), 2 ); |
| 751 | + |
| 752 | + if ( count( $bit ) >= 1 ) { |
| 753 | + list( $name, $value ) = explode( "=", array_shift( $bit ), 2 ); |
711 | 754 | $attr = array(); |
712 | | - foreach( $bit as $piece ) { |
| 755 | + |
| 756 | + foreach ( $bit as $piece ) { |
713 | 757 | $parts = explode( "=", $piece ); |
714 | | - if( count( $parts ) > 1 ) { |
| 758 | + if ( count( $parts ) > 1 ) { |
715 | 759 | $attr[strtolower( $parts[0] )] = $parts[1]; |
716 | 760 | } else { |
717 | 761 | $attr[strtolower( $parts[0] )] = true; |
718 | 762 | } |
719 | 763 | } |
720 | 764 | |
721 | | - if( !isset( $attr['domain'] ) ) { |
| 765 | + if ( !isset( $attr['domain'] ) ) { |
722 | 766 | $attr['domain'] = $domain; |
723 | 767 | } elseif ( !Cookie::validateCookieDomain( $attr['domain'], $domain ) ) { |
724 | 768 | return null; |
725 | 769 | } |
| 770 | + |
726 | 771 | $this->setCookie( $name, $value, $attr ); |
727 | 772 | } |
728 | 773 | } |
729 | 774 | } |
730 | 775 | |
731 | | - |
732 | 776 | /** |
733 | 777 | * HttpRequest implemented using internal curl compiled into PHP |
734 | 778 | */ |
— | — | @@ -747,19 +791,21 @@ |
748 | 792 | |
749 | 793 | public function execute() { |
750 | 794 | parent::execute(); |
| 795 | + |
751 | 796 | if ( !$this->status->isOK() ) { |
752 | 797 | return $this->status; |
753 | 798 | } |
| 799 | + |
754 | 800 | $this->curlOptions[CURLOPT_PROXY] = $this->proxy; |
755 | 801 | $this->curlOptions[CURLOPT_TIMEOUT] = $this->timeout; |
756 | 802 | $this->curlOptions[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0; |
757 | 803 | $this->curlOptions[CURLOPT_WRITEFUNCTION] = $this->callback; |
758 | | - $this->curlOptions[CURLOPT_HEADERFUNCTION] = array($this, "readHeader"); |
| 804 | + $this->curlOptions[CURLOPT_HEADERFUNCTION] = array( $this, "readHeader" ); |
759 | 805 | $this->curlOptions[CURLOPT_MAXREDIRS] = $this->maxRedirects; |
760 | 806 | $this->curlOptions[CURLOPT_ENCODING] = ""; # Enable compression |
761 | 807 | |
762 | 808 | /* not sure these two are actually necessary */ |
763 | | - if(isset($this->reqHeaders['Referer'])) { |
| 809 | + if ( isset( $this->reqHeaders['Referer'] ) ) { |
764 | 810 | $this->curlOptions[CURLOPT_REFERER] = $this->reqHeaders['Referer']; |
765 | 811 | } |
766 | 812 | $this->curlOptions[CURLOPT_USERAGENT] = $this->reqHeaders['User-Agent']; |
— | — | @@ -793,13 +839,15 @@ |
794 | 840 | $this->curlOptions[CURLOPT_HTTPHEADER] = $this->getHeaderList(); |
795 | 841 | |
796 | 842 | $curlHandle = curl_init( $this->url ); |
| 843 | + |
797 | 844 | if ( !curl_setopt_array( $curlHandle, $this->curlOptions ) ) { |
798 | | - throw new MWException("Error setting curl options."); |
| 845 | + throw new MWException( "Error setting curl options." ); |
799 | 846 | } |
| 847 | + |
800 | 848 | if ( $this->followRedirects && $this->canFollowRedirects() ) { |
801 | 849 | if ( ! @curl_setopt( $curlHandle, CURLOPT_FOLLOWLOCATION, true ) ) { |
802 | | - wfDebug( __METHOD__.": Couldn't set CURLOPT_FOLLOWLOCATION. " . |
803 | | - "Probably safe_mode or open_basedir is set.\n"); |
| 850 | + wfDebug( __METHOD__ . ": Couldn't set CURLOPT_FOLLOWLOCATION. " . |
| 851 | + "Probably safe_mode or open_basedir is set.\n" ); |
804 | 852 | // Continue the processing. If it were in curl_setopt_array, |
805 | 853 | // processing would have halted on its entry |
806 | 854 | } |
— | — | @@ -814,13 +862,14 @@ |
815 | 863 | $this->status->fatal( 'http-curl-error', curl_error( $curlHandle ) ); |
816 | 864 | } |
817 | 865 | } else { |
818 | | - $this->headerList = explode("\r\n", $this->headerText); |
| 866 | + $this->headerList = explode( "\r\n", $this->headerText ); |
819 | 867 | } |
820 | 868 | |
821 | 869 | curl_close( $curlHandle ); |
822 | 870 | |
823 | 871 | $this->parseHeader(); |
824 | 872 | $this->setStatus(); |
| 873 | + |
825 | 874 | return $this->status; |
826 | 875 | } |
827 | 876 | |
— | — | @@ -829,10 +878,12 @@ |
830 | 879 | wfDebug( "Cannot follow redirects in safe mode\n" ); |
831 | 880 | return false; |
832 | 881 | } |
| 882 | + |
833 | 883 | if ( !defined( 'CURLOPT_REDIR_PROTOCOLS' ) ) { |
834 | 884 | wfDebug( "Cannot follow redirects with libcurl < 7.19.4 due to CVE-2009-0037\n" ); |
835 | 885 | return false; |
836 | 886 | } |
| 887 | + |
837 | 888 | return true; |
838 | 889 | } |
839 | 890 | } |
— | — | @@ -875,7 +926,7 @@ |
876 | 927 | } |
877 | 928 | |
878 | 929 | $options['method'] = $this->method; |
879 | | - $options['header'] = implode("\r\n", $this->getHeaderList()); |
| 930 | + $options['header'] = implode( "\r\n", $this->getHeaderList() ); |
880 | 931 | // Note that at some future point we may want to support |
881 | 932 | // HTTP/1.1, but we'd have to write support for chunking |
882 | 933 | // in version of PHP < 5.3.1 |
— | — | @@ -891,7 +942,7 @@ |
892 | 943 | |
893 | 944 | $oldTimeout = false; |
894 | 945 | if ( version_compare( '5.2.1', phpversion(), '>' ) ) { |
895 | | - $oldTimeout = ini_set('default_socket_timeout', $this->timeout); |
| 946 | + $oldTimeout = ini_set( 'default_socket_timeout', $this->timeout ); |
896 | 947 | } else { |
897 | 948 | $options['timeout'] = $this->timeout; |
898 | 949 | } |
— | — | @@ -901,17 +952,21 @@ |
902 | 953 | $this->headerList = array(); |
903 | 954 | $reqCount = 0; |
904 | 955 | $url = $this->url; |
| 956 | + |
905 | 957 | do { |
906 | 958 | $reqCount++; |
907 | 959 | wfSuppressWarnings(); |
908 | 960 | $fh = fopen( $url, "r", false, $context ); |
909 | 961 | wfRestoreWarnings(); |
| 962 | + |
910 | 963 | if ( !$fh ) { |
911 | 964 | break; |
912 | 965 | } |
| 966 | + |
913 | 967 | $result = stream_get_meta_data( $fh ); |
914 | 968 | $this->headerList = $result['wrapper_data']; |
915 | 969 | $this->parseHeader(); |
| 970 | + |
916 | 971 | if ( !$manuallyRedirect || !$this->followRedirects ) { |
917 | 972 | break; |
918 | 973 | } |
— | — | @@ -921,16 +976,18 @@ |
922 | 977 | break; |
923 | 978 | } |
924 | 979 | # Check security of URL |
925 | | - $url = $this->getResponseHeader("Location"); |
| 980 | + $url = $this->getResponseHeader( "Location" ); |
| 981 | + |
926 | 982 | if ( substr( $url, 0, 7 ) !== 'http://' ) { |
927 | | - wfDebug( __METHOD__.": insecure redirection\n" ); |
| 983 | + wfDebug( __METHOD__ . ": insecure redirection\n" ); |
928 | 984 | break; |
929 | 985 | } |
930 | 986 | } while ( true ); |
931 | 987 | |
932 | 988 | if ( $oldTimeout !== false ) { |
933 | | - ini_set('default_socket_timeout', $oldTimeout); |
| 989 | + ini_set( 'default_socket_timeout', $oldTimeout ); |
934 | 990 | } |
| 991 | + |
935 | 992 | $this->setStatus(); |
936 | 993 | |
937 | 994 | if ( $fh === false ) { |
— | — | @@ -943,13 +1000,15 @@ |
944 | 1001 | return $this->status; |
945 | 1002 | } |
946 | 1003 | |
947 | | - if($this->status->isOK()) { |
| 1004 | + if ( $this->status->isOK() ) { |
948 | 1005 | while ( !feof( $fh ) ) { |
949 | 1006 | $buf = fread( $fh, 8192 ); |
| 1007 | + |
950 | 1008 | if ( $buf === false ) { |
951 | 1009 | $this->status->fatal( 'http-read-error' ); |
952 | 1010 | break; |
953 | 1011 | } |
| 1012 | + |
954 | 1013 | if ( strlen( $buf ) ) { |
955 | 1014 | call_user_func( $this->callback, $fh, $buf ); |
956 | 1015 | } |
Index: trunk/phase3/includes/Skin.php |
— | — | @@ -40,20 +40,24 @@ |
41 | 41 | static function getSkinNames() { |
42 | 42 | global $wgValidSkinNames; |
43 | 43 | static $skinsInitialised = false; |
| 44 | + |
44 | 45 | if ( !$skinsInitialised ) { |
45 | 46 | # Get a list of available skins |
46 | 47 | # Build using the regular expression '^(.*).php$' |
47 | 48 | # Array keys are all lower case, array value keep the case used by filename |
48 | 49 | # |
49 | 50 | wfProfileIn( __METHOD__ . '-init' ); |
| 51 | + |
50 | 52 | global $wgStyleDirectory; |
| 53 | + |
51 | 54 | $skinDir = dir( $wgStyleDirectory ); |
52 | 55 | |
53 | 56 | # while code from www.php.net |
54 | | - while( false !== ( $file = $skinDir->read() ) ) { |
| 57 | + while ( false !== ( $file = $skinDir->read() ) ) { |
55 | 58 | // Skip non-PHP files, hidden files, and '.dep' includes |
56 | 59 | $matches = array(); |
57 | | - if( preg_match( '/^([^.]*)\.php$/', $file, $matches ) ) { |
| 60 | + |
| 61 | + if ( preg_match( '/^([^.]*)\.php$/', $file, $matches ) ) { |
58 | 62 | $aSkin = $matches[1]; |
59 | 63 | $wgValidSkinNames[strtolower( $aSkin )] = $aSkin; |
60 | 64 | } |
— | — | @@ -73,10 +77,13 @@ |
74 | 78 | */ |
75 | 79 | public static function getUsableSkins() { |
76 | 80 | global $wgSkipSkins; |
| 81 | + |
77 | 82 | $usableSkins = self::getSkinNames(); |
| 83 | + |
78 | 84 | foreach ( $wgSkipSkins as $skip ) { |
79 | 85 | unset( $usableSkins[$skip] ); |
80 | 86 | } |
| 87 | + |
81 | 88 | return $usableSkins; |
82 | 89 | } |
83 | 90 | |
— | — | @@ -89,15 +96,16 @@ |
90 | 97 | */ |
91 | 98 | static function normalizeKey( $key ) { |
92 | 99 | global $wgDefaultSkin; |
| 100 | + |
93 | 101 | $skinNames = Skin::getSkinNames(); |
94 | 102 | |
95 | | - if( $key == '' ) { |
| 103 | + if ( $key == '' ) { |
96 | 104 | // Don't return the default immediately; |
97 | 105 | // in a misconfiguration we need to fall back. |
98 | 106 | $key = $wgDefaultSkin; |
99 | 107 | } |
100 | 108 | |
101 | | - if( isset( $skinNames[$key] ) ) { |
| 109 | + if ( isset( $skinNames[$key] ) ) { |
102 | 110 | return $key; |
103 | 111 | } |
104 | 112 | |
— | — | @@ -109,13 +117,13 @@ |
110 | 118 | 2 => 'cologneblue' |
111 | 119 | ); |
112 | 120 | |
113 | | - if( isset( $fallback[$key] ) ) { |
| 121 | + if ( isset( $fallback[$key] ) ) { |
114 | 122 | $key = $fallback[$key]; |
115 | 123 | } |
116 | 124 | |
117 | | - if( isset( $skinNames[$key] ) ) { |
| 125 | + if ( isset( $skinNames[$key] ) ) { |
118 | 126 | return $key; |
119 | | - } else if( isset( $skinNames[$wgDefaultSkin] ) ) { |
| 127 | + } else if ( isset( $skinNames[$wgDefaultSkin] ) ) { |
120 | 128 | return $wgDefaultSkin; |
121 | 129 | } else { |
122 | 130 | return 'vector'; |
— | — | @@ -140,13 +148,14 @@ |
141 | 149 | if ( !class_exists( $className ) ) { |
142 | 150 | // Preload base classes to work around APC/PHP5 bug |
143 | 151 | $deps = "{$wgStyleDirectory}/{$skinName}.deps.php"; |
144 | | - if( file_exists( $deps ) ) { |
| 152 | + |
| 153 | + if ( file_exists( $deps ) ) { |
145 | 154 | include_once( $deps ); |
146 | 155 | } |
147 | 156 | require_once( "{$wgStyleDirectory}/{$skinName}.php" ); |
148 | 157 | |
149 | 158 | # Check if we got if not failback to default skin |
150 | | - if( !class_exists( $className ) ) { |
| 159 | + if ( !class_exists( $className ) ) { |
151 | 160 | # DO NOT die if the class isn't found. This breaks maintenance |
152 | 161 | # scripts and can cause a user account to be unrecoverable |
153 | 162 | # except by SQL manipulation if a previously valid skin name |
— | — | @@ -176,7 +185,9 @@ |
177 | 186 | if ( $wgOut->isQuickbarSuppressed() ) { |
178 | 187 | return 0; |
179 | 188 | } |
| 189 | + |
180 | 190 | $q = $wgUser->getOption( 'quickbar', 0 ); |
| 191 | + |
181 | 192 | return $q; |
182 | 193 | } |
183 | 194 | |
— | — | @@ -189,11 +200,11 @@ |
190 | 201 | # should not matter, but Konqueror (3.5.9 at least) incorrectly |
191 | 202 | # uses whichever one appears later in the HTML source. Make sure |
192 | 203 | # apple-touch-icon is specified first to avoid this. |
193 | | - if( false !== $wgAppleTouchIcon ) { |
| 204 | + if ( false !== $wgAppleTouchIcon ) { |
194 | 205 | $out->addLink( array( 'rel' => 'apple-touch-icon', 'href' => $wgAppleTouchIcon ) ); |
195 | 206 | } |
196 | 207 | |
197 | | - if( false !== $wgFavicon ) { |
| 208 | + if ( false !== $wgFavicon ) { |
198 | 209 | $out->addLink( array( 'rel' => 'shortcut icon', 'href' => $wgFavicon ) ); |
199 | 210 | } |
200 | 211 | |
— | — | @@ -203,7 +214,7 @@ |
204 | 215 | 'type' => 'application/opensearchdescription+xml', |
205 | 216 | 'href' => wfScript( 'opensearch_desc' ), |
206 | 217 | 'title' => wfMsgForContent( 'opensearch-desc' ), |
207 | | - )); |
| 218 | + ) ); |
208 | 219 | |
209 | 220 | $this->addMetadataLinks( $out ); |
210 | 221 | |
— | — | @@ -245,16 +256,17 @@ |
246 | 257 | global $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf; |
247 | 258 | global $wgRightsPage, $wgRightsUrl; |
248 | 259 | |
249 | | - if( $out->isArticleRelated() ) { |
| 260 | + if ( $out->isArticleRelated() ) { |
250 | 261 | # note: buggy CC software only reads first "meta" link |
251 | | - if( $wgEnableCreativeCommonsRdf ) { |
| 262 | + if ( $wgEnableCreativeCommonsRdf ) { |
252 | 263 | $out->addMetadataLink( array( |
253 | 264 | 'title' => 'Creative Commons', |
254 | 265 | 'type' => 'application/rdf+xml', |
255 | 266 | 'href' => $this->mTitle->getLocalURL( 'action=creativecommons' ) ) |
256 | 267 | ); |
257 | 268 | } |
258 | | - if( $wgEnableDublinCoreRdf ) { |
| 269 | + |
| 270 | + if ( $wgEnableDublinCoreRdf ) { |
259 | 271 | $out->addMetadataLink( array( |
260 | 272 | 'title' => 'Dublin Core', |
261 | 273 | 'type' => 'application/rdf+xml', |
— | — | @@ -263,16 +275,19 @@ |
264 | 276 | } |
265 | 277 | } |
266 | 278 | $copyright = ''; |
267 | | - if( $wgRightsPage ) { |
| 279 | + if ( $wgRightsPage ) { |
268 | 280 | $copy = Title::newFromText( $wgRightsPage ); |
269 | | - if( $copy ) { |
| 281 | + |
| 282 | + if ( $copy ) { |
270 | 283 | $copyright = $copy->getLocalURL(); |
271 | 284 | } |
272 | 285 | } |
273 | | - if( !$copyright && $wgRightsUrl ) { |
| 286 | + |
| 287 | + if ( !$copyright && $wgRightsUrl ) { |
274 | 288 | $copyright = $wgRightsUrl; |
275 | 289 | } |
276 | | - if( $copyright ) { |
| 290 | + |
| 291 | + if ( $copyright ) { |
277 | 292 | $out->addLink( array( |
278 | 293 | 'rel' => 'copyright', |
279 | 294 | 'href' => $copyright ) |
— | — | @@ -339,9 +354,9 @@ |
340 | 355 | $out->out( "\n</body></html>" ); |
341 | 356 | wfProfileOut( __METHOD__ ); |
342 | 357 | } |
343 | | - |
| 358 | + |
344 | 359 | static function makeVariablesScript( $data ) { |
345 | | - if( $data ) { |
| 360 | + if ( $data ) { |
346 | 361 | return Html::inlineScript( 'mediaWiki.config.set(' . json_encode( $data ) . ');' ); |
347 | 362 | } else { |
348 | 363 | return ''; |
— | — | @@ -359,6 +374,7 @@ |
360 | 375 | # Weird back-compat stuff. |
361 | 376 | $skinName = $skinName['skinname']; |
362 | 377 | } |
| 378 | + |
363 | 379 | global $wgScript, $wgTitle, $wgStylePath, $wgUser, $wgScriptExtension; |
364 | 380 | global $wgArticlePath, $wgScriptPath, $wgServer, $wgContLang, $wgLang; |
365 | 381 | global $wgOut, $wgArticle; |
— | — | @@ -422,32 +438,34 @@ |
423 | 439 | 'wgSiteName' => $wgSitename, |
424 | 440 | 'wgCategories' => $wgOut->getCategories(), |
425 | 441 | ); |
| 442 | + |
426 | 443 | if ( $wgContLang->hasVariants() ) { |
427 | 444 | $vars['wgUserVariant'] = $wgContLang->getPreferredVariant(); |
428 | 445 | } |
429 | 446 | |
430 | 447 | // if on upload page output the extension list & js_upload |
431 | | - if( SpecialPage::resolveAlias( $wgTitle->getDBkey() ) == 'Upload' ) { |
| 448 | + if ( SpecialPage::resolveAlias( $wgTitle->getDBkey() ) == 'Upload' ) { |
432 | 449 | global $wgFileExtensions; |
433 | 450 | $vars['wgFileExtensions'] = $wgFileExtensions; |
434 | 451 | } |
435 | 452 | |
436 | | - if( $wgUseAjax && $wgEnableMWSuggest && !$wgUser->getOption( 'disablesuggest', false ) ) { |
| 453 | + if ( $wgUseAjax && $wgEnableMWSuggest && !$wgUser->getOption( 'disablesuggest', false ) ) { |
437 | 454 | $vars['wgMWSuggestTemplate'] = SearchEngine::getMWSuggestTemplate(); |
438 | 455 | $vars['wgDBname'] = $wgDBname; |
439 | 456 | $vars['wgSearchNamespaces'] = SearchEngine::userNamespaces( $wgUser ); |
440 | 457 | $vars['wgMWSuggestMessages'] = array( wfMsg( 'search-mwsuggest-enabled' ), wfMsg( 'search-mwsuggest-disabled' ) ); |
441 | 458 | } |
442 | 459 | |
443 | | - foreach( $wgRestrictionTypes as $type ) { |
| 460 | + foreach ( $wgRestrictionTypes as $type ) { |
444 | 461 | $vars['wgRestriction' . ucfirst( $type )] = $wgTitle->getRestrictions( $type ); |
445 | 462 | } |
446 | 463 | |
447 | 464 | if ( $wgOut->isArticleRelated() && $wgUseAjax && $wgAjaxWatch && $wgUser->isLoggedIn() ) { |
448 | 465 | $msgs = (object)array(); |
| 466 | + |
449 | 467 | foreach ( array( 'watch', 'unwatch', 'watching', 'unwatching', |
450 | 468 | 'tooltip-ca-watch', 'tooltip-ca-unwatch' ) as $msgName ) { |
451 | | - $msgs->{$msgName . 'Msg'} = wfMsg( $msgName ); |
| 469 | + $msgs-> { $msgName . 'Msg' } = wfMsg( $msgName ); |
452 | 470 | } |
453 | 471 | $vars['wgAjaxWatch'] = $msgs; |
454 | 472 | } |
— | — | @@ -471,18 +489,19 @@ |
472 | 490 | public function userCanPreview( $action ) { |
473 | 491 | global $wgRequest, $wgUser; |
474 | 492 | |
475 | | - if( $action != 'submit' ) { |
| 493 | + if ( $action != 'submit' ) { |
476 | 494 | return false; |
477 | 495 | } |
478 | | - if( !$wgRequest->wasPosted() ) { |
| 496 | + if ( !$wgRequest->wasPosted() ) { |
479 | 497 | return false; |
480 | 498 | } |
481 | | - if( !$this->mTitle->userCanEditCssSubpage() ) { |
| 499 | + if ( !$this->mTitle->userCanEditCssSubpage() ) { |
482 | 500 | return false; |
483 | 501 | } |
484 | | - if( !$this->mTitle->userCanEditJsSubpage() ) { |
| 502 | + if ( !$this->mTitle->userCanEditJsSubpage() ) { |
485 | 503 | return false; |
486 | 504 | } |
| 505 | + |
487 | 506 | return $wgUser->matchEditToken( |
488 | 507 | $wgRequest->getVal( 'wpEditToken' ) ); |
489 | 508 | } |
— | — | @@ -505,7 +524,8 @@ |
506 | 525 | global $wgStylePath; |
507 | 526 | |
508 | 527 | wfProfileIn( __METHOD__ ); |
509 | | - if( !$skinName ) { |
| 528 | + |
| 529 | + if ( !$skinName ) { |
510 | 530 | $skinName = $this->getSkinName(); |
511 | 531 | } |
512 | 532 | |
— | — | @@ -513,16 +533,20 @@ |
514 | 534 | $s .= "var skin = '" . Xml::escapeJsString( $skinName ) . "';\n"; |
515 | 535 | $s .= "var stylepath = '" . Xml::escapeJsString( $wgStylePath ) . "';"; |
516 | 536 | $s .= "\n\n/* MediaWiki:Common.js */\n"; |
| 537 | + |
517 | 538 | $commonJs = wfMsgExt( 'common.js', 'content' ); |
| 539 | + |
518 | 540 | if ( !wfEmptyMsg( 'common.js', $commonJs ) ) { |
519 | 541 | $s .= $commonJs; |
520 | 542 | } |
521 | 543 | |
522 | 544 | $s .= "\n\n/* MediaWiki:" . ucfirst( $skinName ) . ".js */\n"; |
| 545 | + |
523 | 546 | // avoid inclusion of non defined user JavaScript (with custom skins only) |
524 | 547 | // by checking for default message content |
525 | 548 | $msgKey = ucfirst( $skinName ) . '.js'; |
526 | 549 | $userJS = wfMsgExt( $msgKey, 'content' ); |
| 550 | + |
527 | 551 | if ( !wfEmptyMsg( $msgKey, $userJS ) ) { |
528 | 552 | $s .= $userJS; |
529 | 553 | } |
— | — | @@ -536,8 +560,10 @@ |
537 | 561 | */ |
538 | 562 | public function generateUserStylesheet() { |
539 | 563 | wfProfileIn( __METHOD__ ); |
| 564 | + |
540 | 565 | $s = "/* generated user stylesheet */\n" . |
541 | 566 | $this->reallyGenerateUserStylesheet(); |
| 567 | + |
542 | 568 | wfProfileOut( __METHOD__ ); |
543 | 569 | return $s; |
544 | 570 | } |
— | — | @@ -548,12 +574,15 @@ |
549 | 575 | */ |
550 | 576 | protected function reallyGenerateUserStylesheet() { |
551 | 577 | global $wgUser; |
| 578 | + |
552 | 579 | $s = ''; |
553 | | - if( ( $undopt = $wgUser->getOption( 'underline' ) ) < 2 ) { |
| 580 | + |
| 581 | + if ( ( $undopt = $wgUser->getOption( 'underline' ) ) < 2 ) { |
554 | 582 | $underline = $undopt ? 'underline' : 'none'; |
555 | 583 | $s .= "a { text-decoration: $underline; }\n"; |
556 | 584 | } |
557 | | - if( $wgUser->getOption( 'highlightbroken' ) ) { |
| 585 | + |
| 586 | + if ( $wgUser->getOption( 'highlightbroken' ) ) { |
558 | 587 | $s .= "a.new, #quickbar a.new { color: #CC2200; }\n"; |
559 | 588 | } else { |
560 | 589 | $s .= <<<CSS |
— | — | @@ -571,19 +600,25 @@ |
572 | 601 | } |
573 | 602 | CSS; |
574 | 603 | } |
575 | | - if( $wgUser->getOption( 'justify' ) ) { |
| 604 | + |
| 605 | + if ( $wgUser->getOption( 'justify' ) ) { |
576 | 606 | $s .= "#article, #bodyContent, #mw_content { text-align: justify; }\n"; |
577 | 607 | } |
578 | | - if( !$wgUser->getOption( 'showtoc' ) ) { |
| 608 | + |
| 609 | + if ( !$wgUser->getOption( 'showtoc' ) ) { |
579 | 610 | $s .= "#toc { display: none; }\n"; |
580 | 611 | } |
581 | | - if( !$wgUser->getOption( 'editsection' ) ) { |
| 612 | + |
| 613 | + if ( !$wgUser->getOption( 'editsection' ) ) { |
582 | 614 | $s .= ".editsection { display: none; }\n"; |
583 | 615 | } |
| 616 | + |
584 | 617 | $fontstyle = $wgUser->getOption( 'editfont' ); |
| 618 | + |
585 | 619 | if ( $fontstyle !== 'default' ) { |
586 | 620 | $s .= "textarea { font-family: $fontstyle; }\n"; |
587 | 621 | } |
| 622 | + |
588 | 623 | return $s; |
589 | 624 | } |
590 | 625 | |
— | — | @@ -610,44 +645,51 @@ |
611 | 646 | |
612 | 647 | // If we use the site's dynamic CSS, throw that in, too |
613 | 648 | // Per-site custom styles |
614 | | - if( $wgUseSiteCss ) { |
| 649 | + if ( $wgUseSiteCss ) { |
615 | 650 | global $wgHandheldStyle; |
| 651 | + |
616 | 652 | $query = wfArrayToCGI( self::getDynamicStylesheetQuery() ); |
617 | 653 | # Site settings must override extension css! (bug 15025) |
618 | 654 | $out->addStyle( self::makeNSUrl( 'Common.css', $query, NS_MEDIAWIKI ) ); |
619 | 655 | $out->addStyle( self::makeNSUrl( 'Print.css', $query, NS_MEDIAWIKI ), 'print' ); |
620 | | - if( $wgHandheldStyle ) { |
| 656 | + |
| 657 | + if ( $wgHandheldStyle ) { |
621 | 658 | $out->addStyle( self::makeNSUrl( 'Handheld.css', $query, NS_MEDIAWIKI ), 'handheld' ); |
622 | 659 | } |
623 | 660 | $out->addStyle( self::makeNSUrl( $this->getSkinName() . '.css', $query, NS_MEDIAWIKI ) ); |
624 | 661 | } |
625 | 662 | |
626 | 663 | global $wgAllowUserCssPrefs; |
627 | | - if( $wgAllowUserCssPrefs ){ |
628 | | - if( $wgUser->isLoggedIn() ) { |
| 664 | + |
| 665 | + if ( $wgAllowUserCssPrefs ) { |
| 666 | + if ( $wgUser->isLoggedIn() ) { |
629 | 667 | // Ensure that logged-in users' generated CSS isn't clobbered |
630 | 668 | // by anons' publicly cacheable generated CSS. |
631 | 669 | $siteargs['smaxage'] = '0'; |
632 | 670 | $siteargs['ts'] = $wgUser->mTouched; |
633 | 671 | } |
| 672 | + |
634 | 673 | // Per-user styles based on preferences |
635 | 674 | $siteargs['gen'] = 'css'; |
636 | | - if( ( $us = $wgRequest->getVal( 'useskin', '' ) ) !== '' ) { |
| 675 | + |
| 676 | + if ( ( $us = $wgRequest->getVal( 'useskin', '' ) ) !== '' ) { |
637 | 677 | $siteargs['useskin'] = $us; |
638 | 678 | } |
| 679 | + |
639 | 680 | $out->addStyle( self::makeUrl( '-', wfArrayToCGI( $siteargs ) ) ); |
640 | 681 | } |
641 | 682 | |
642 | 683 | // Per-user custom style pages |
643 | | - if( $wgAllowUserCss && $wgUser->isLoggedIn() ) { |
| 684 | + if ( $wgAllowUserCss && $wgUser->isLoggedIn() ) { |
644 | 685 | $action = $wgRequest->getVal( 'action' ); |
| 686 | + |
645 | 687 | # If we're previewing the CSS page, use it |
646 | | - if( $this->mTitle->isCssSubpage() && $this->userCanPreview( $action ) ) { |
| 688 | + if ( $this->mTitle->isCssSubpage() && $this->userCanPreview( $action ) ) { |
647 | 689 | // @FIXME: properly escape the cdata! |
648 | 690 | $out->addInlineStyle( $wgRequest->getText( 'wpTextbox1' ) ); |
649 | 691 | } else { |
650 | 692 | $names = array( 'common', $this->getSkinName() ); |
651 | | - foreach( $names as $name ) { |
| 693 | + foreach ( $names as $name ) { |
652 | 694 | $out->addStyle( self::makeUrl( |
653 | 695 | $this->userpage . '/' . $name . '.css', |
654 | 696 | 'action=raw&ctype=text/css' ) |
— | — | @@ -666,6 +708,7 @@ |
667 | 709 | */ |
668 | 710 | public static function getDynamicStylesheetQuery() { |
669 | 711 | global $wgSquidMaxage; |
| 712 | + |
670 | 713 | return array( |
671 | 714 | 'action' => 'raw', |
672 | 715 | 'maxage' => $wgSquidMaxage, |
— | — | @@ -689,14 +732,17 @@ |
690 | 733 | |
691 | 734 | function getPageClasses( $title ) { |
692 | 735 | $numeric = 'ns-' . $title->getNamespace(); |
693 | | - if( $title->getNamespace() == NS_SPECIAL ) { |
| 736 | + |
| 737 | + if ( $title->getNamespace() == NS_SPECIAL ) { |
694 | 738 | $type = 'ns-special'; |
695 | | - } elseif( $title->isTalkPage() ) { |
| 739 | + } elseif ( $title->isTalkPage() ) { |
696 | 740 | $type = 'ns-talk'; |
697 | 741 | } else { |
698 | 742 | $type = 'ns-subject'; |
699 | 743 | } |
| 744 | + |
700 | 745 | $name = Sanitizer::escapeClass( 'page-' . $title->getPrefixedText() ); |
| 746 | + |
701 | 747 | return "$numeric $type $name"; |
702 | 748 | } |
703 | 749 | |
— | — | @@ -724,7 +770,7 @@ |
725 | 771 | $qb = $this->qbSetting(); |
726 | 772 | |
727 | 773 | $langlinks = $this->otherLanguages(); |
728 | | - if( $langlinks ) { |
| 774 | + if ( $langlinks ) { |
729 | 775 | $rows = 2; |
730 | 776 | $borderhack = ''; |
731 | 777 | } else { |
— | — | @@ -738,16 +784,18 @@ |
739 | 785 | |
740 | 786 | $shove = ( $qb != 0 ); |
741 | 787 | $left = ( $qb == 1 || $qb == 3 ); |
742 | | - if( $wgContLang->isRTL() ) { |
| 788 | + |
| 789 | + if ( $wgContLang->isRTL() ) { |
743 | 790 | $left = !$left; |
744 | 791 | } |
745 | 792 | |
746 | | - if( !$shove ) { |
| 793 | + if ( !$shove ) { |
747 | 794 | $s .= "<td class='top' align='left' valign='top' rowspan='{$rows}'>\n" . |
748 | 795 | $this->logoText() . '</td>'; |
749 | | - } elseif( $left ) { |
| 796 | + } elseif ( $left ) { |
750 | 797 | $s .= $this->getQuickbarCompensator( $rows ); |
751 | 798 | } |
| 799 | + |
752 | 800 | $l = $wgContLang->alignStart(); |
753 | 801 | $s .= "<td {$borderhack} align='$l' valign='top'>\n"; |
754 | 802 | |
— | — | @@ -766,16 +814,19 @@ |
767 | 815 | if ( $shove && !$left ) { # Right |
768 | 816 | $s .= $this->getQuickbarCompensator( $rows ); |
769 | 817 | } |
| 818 | + |
770 | 819 | $s .= "</tr>\n</table>\n</div>\n"; |
771 | 820 | $s .= "\n<div id='article'>\n"; |
772 | 821 | |
773 | 822 | $notice = wfGetSiteNotice(); |
774 | | - if( $notice ) { |
| 823 | + |
| 824 | + if ( $notice ) { |
775 | 825 | $s .= "\n<div id='siteNotice'>$notice</div>\n"; |
776 | 826 | } |
777 | 827 | $s .= $this->pageTitle(); |
778 | 828 | $s .= $this->pageSubtitle(); |
779 | 829 | $s .= $this->getCategories(); |
| 830 | + |
780 | 831 | wfProfileOut( __METHOD__ ); |
781 | 832 | return $s; |
782 | 833 | } |
— | — | @@ -784,7 +835,7 @@ |
785 | 836 | global $wgOut, $wgUseCategoryBrowser; |
786 | 837 | global $wgContLang, $wgUser; |
787 | 838 | |
788 | | - if( count( $wgOut->mCategoryLinks ) == 0 ) { |
| 839 | + if ( count( $wgOut->mCategoryLinks ) == 0 ) { |
789 | 840 | return ''; |
790 | 841 | } |
791 | 842 | |
— | — | @@ -800,6 +851,7 @@ |
801 | 852 | $allCats = $wgOut->getCategoryLinks(); |
802 | 853 | $s = ''; |
803 | 854 | $colon = wfMsgExt( 'colon-separator', 'escapenoentities' ); |
| 855 | + |
804 | 856 | if ( !empty( $allCats['normal'] ) ) { |
805 | 857 | $t = $embed . implode( "{$pop} {$sep} {$embed}" , $allCats['normal'] ) . $pop; |
806 | 858 | |
— | — | @@ -812,12 +864,13 @@ |
813 | 865 | # Hidden categories |
814 | 866 | if ( isset( $allCats['hidden'] ) ) { |
815 | 867 | if ( $wgUser->getBoolOption( 'showhiddencats' ) ) { |
816 | | - $class ='mw-hidden-cats-user-shown'; |
| 868 | + $class = 'mw-hidden-cats-user-shown'; |
817 | 869 | } elseif ( $this->mTitle->getNamespace() == NS_CATEGORY ) { |
818 | 870 | $class = 'mw-hidden-cats-ns-shown'; |
819 | 871 | } else { |
820 | 872 | $class = 'mw-hidden-cats-hidden'; |
821 | 873 | } |
| 874 | + |
822 | 875 | $s .= "<div id=\"mw-hidden-catlinks\" class=\"$class\">" . |
823 | 876 | wfMsgExt( 'hidden-categories', array( 'parsemag', 'escapenoentities' ), count( $allCats['hidden'] ) ) . |
824 | 877 | $colon . $embed . implode( "$pop $sep $embed", $allCats['hidden'] ) . $pop . |
— | — | @@ -826,7 +879,7 @@ |
827 | 880 | |
828 | 881 | # optional 'dmoz-like' category browser. Will be shown under the list |
829 | 882 | # of categories an article belong to |
830 | | - if( $wgUseCategoryBrowser ) { |
| 883 | + if ( $wgUseCategoryBrowser ) { |
831 | 884 | $s .= '<br /><hr />'; |
832 | 885 | |
833 | 886 | # get a big array of the parents tree |
— | — | @@ -852,18 +905,21 @@ |
853 | 906 | */ |
854 | 907 | function drawCategoryBrowser( $tree, &$skin ) { |
855 | 908 | $return = ''; |
856 | | - foreach( $tree as $element => $parent ) { |
857 | | - if( empty( $parent ) ) { |
| 909 | + |
| 910 | + foreach ( $tree as $element => $parent ) { |
| 911 | + if ( empty( $parent ) ) { |
858 | 912 | # element start a new list |
859 | 913 | $return .= "\n"; |
860 | 914 | } else { |
861 | 915 | # grab the others elements |
862 | 916 | $return .= $this->drawCategoryBrowser( $parent, $skin ) . ' > '; |
863 | 917 | } |
| 918 | + |
864 | 919 | # add our current element to the list |
865 | 920 | $eltitle = Title::newFromText( $element ); |
866 | 921 | $return .= $skin->link( $eltitle, $eltitle->getText() ); |
867 | 922 | } |
| 923 | + |
868 | 924 | return $return; |
869 | 925 | } |
870 | 926 | |
— | — | @@ -872,13 +928,14 @@ |
873 | 929 | |
874 | 930 | $classes = 'catlinks'; |
875 | 931 | |
| 932 | + global $wgOut, $wgUser; |
| 933 | + |
876 | 934 | // Check what we're showing |
877 | | - global $wgOut, $wgUser; |
878 | 935 | $allCats = $wgOut->getCategoryLinks(); |
879 | 936 | $showHidden = $wgUser->getBoolOption( 'showhiddencats' ) || |
880 | 937 | $this->mTitle->getNamespace() == NS_CATEGORY; |
881 | 938 | |
882 | | - if( empty( $allCats['normal'] ) && !( !empty( $allCats['hidden'] ) && $showHidden ) ) { |
| 939 | + if ( empty( $allCats['normal'] ) && !( !empty( $allCats['hidden'] ) && $showHidden ) ) { |
883 | 940 | $classes .= ' catlinks-allhidden'; |
884 | 941 | } |
885 | 942 | |
— | — | @@ -906,10 +963,10 @@ |
907 | 964 | protected function afterContentHook() { |
908 | 965 | $data = ''; |
909 | 966 | |
910 | | - if( wfRunHooks( 'SkinAfterContent', array( &$data, $this ) ) ) { |
| 967 | + if ( wfRunHooks( 'SkinAfterContent', array( &$data, $this ) ) ) { |
911 | 968 | // adding just some spaces shouldn't toggle the output |
912 | 969 | // of the whole <div/>, so we use trim() here |
913 | | - if( trim( $data ) != '' ) { |
| 970 | + if ( trim( $data ) != '' ) { |
914 | 971 | // Doing this here instead of in the skins to |
915 | 972 | // ensure that the div has the same ID in all |
916 | 973 | // skins |
— | — | @@ -931,11 +988,13 @@ |
932 | 989 | */ |
933 | 990 | protected function generateDebugHTML() { |
934 | 991 | global $wgShowDebug, $wgOut; |
| 992 | + |
935 | 993 | if ( $wgShowDebug ) { |
936 | 994 | $listInternals = $this->formatDebugHTML( $wgOut->mDebugtext ); |
937 | 995 | return "\n<hr />\n<strong>Debug data:</strong><ul style=\"font-family:monospace;\" id=\"mw-debug-html\">" . |
938 | 996 | $listInternals . "</ul>\n"; |
939 | 997 | } |
| 998 | + |
940 | 999 | return ''; |
941 | 1000 | } |
942 | 1001 | |
— | — | @@ -943,7 +1002,8 @@ |
944 | 1003 | $lines = explode( "\n", $debugText ); |
945 | 1004 | $curIdent = 0; |
946 | 1005 | $ret = '<li>'; |
947 | | - foreach( $lines as $line ) { |
| 1006 | + |
| 1007 | + foreach ( $lines as $line ) { |
948 | 1008 | $m = array(); |
949 | 1009 | $display = ltrim( $line ); |
950 | 1010 | $ident = strlen( $line ) - strlen( $display ); |
— | — | @@ -972,7 +1032,9 @@ |
973 | 1033 | |
974 | 1034 | $curIdent = $ident; |
975 | 1035 | } |
| 1036 | + |
976 | 1037 | $ret .= str_repeat( '</li></ul>', $curIdent ) . '</li>'; |
| 1038 | + |
977 | 1039 | return $ret; |
978 | 1040 | } |
979 | 1041 | |
— | — | @@ -993,6 +1055,7 @@ |
994 | 1056 | function bottomScripts( $out ) { |
995 | 1057 | $bottomScriptText = "\n" . $out->getHeadScripts( $this ); |
996 | 1058 | wfRunHooks( 'SkinAfterBottomScripts', array( $this, &$bottomScriptText ) ); |
| 1059 | + |
997 | 1060 | return $bottomScriptText; |
998 | 1061 | } |
999 | 1062 | |
— | — | @@ -1021,11 +1084,14 @@ |
1022 | 1085 | |
1023 | 1086 | $s[] = $this->printableLink(); |
1024 | 1087 | $disclaimer = $this->disclaimerLink(); # may be empty |
1025 | | - if( $disclaimer ) { |
| 1088 | + |
| 1089 | + if ( $disclaimer ) { |
1026 | 1090 | $s[] = $disclaimer; |
1027 | 1091 | } |
| 1092 | + |
1028 | 1093 | $privacy = $this->privacyLink(); # may be empty too |
1029 | | - if( $privacy ) { |
| 1094 | + |
| 1095 | + if ( $privacy ) { |
1030 | 1096 | $s[] = $privacy; |
1031 | 1097 | } |
1032 | 1098 | |
— | — | @@ -1033,13 +1099,15 @@ |
1034 | 1100 | if ( $this->mTitle->getNamespace() == NS_FILE ) { |
1035 | 1101 | $name = $this->mTitle->getDBkey(); |
1036 | 1102 | $image = wfFindFile( $this->mTitle ); |
1037 | | - if( $image ) { |
| 1103 | + |
| 1104 | + if ( $image ) { |
1038 | 1105 | $link = htmlspecialchars( $image->getURL() ); |
1039 | 1106 | $style = $this->getInternalLinkAttributes( $link, $name ); |
1040 | 1107 | $s[] = "<a href=\"{$link}\"{$style}>{$name}</a>"; |
1041 | 1108 | } |
1042 | 1109 | } |
1043 | 1110 | } |
| 1111 | + |
1044 | 1112 | if ( 'history' == $action || isset( $diff ) || isset( $oldid ) ) { |
1045 | 1113 | $s[] .= $this->link( |
1046 | 1114 | $this->mTitle, |
— | — | @@ -1053,7 +1121,7 @@ |
1054 | 1122 | if ( $wgUser->getNewtalk() ) { |
1055 | 1123 | # do not show "You have new messages" text when we are viewing our |
1056 | 1124 | # own talk page |
1057 | | - if( !$this->mTitle->equals( $wgUser->getTalkPage() ) ) { |
| 1125 | + if ( !$this->mTitle->equals( $wgUser->getTalkPage() ) ) { |
1058 | 1126 | $tl = $this->link( |
1059 | 1127 | $wgUser->getTalkPage(), |
1060 | 1128 | wfMsgHtml( 'newmessageslink' ), |
— | — | @@ -1069,7 +1137,7 @@ |
1070 | 1138 | array( 'diff' => 'cur' ), |
1071 | 1139 | array( 'known', 'noclasses' ) |
1072 | 1140 | ); |
1073 | | - $s[] = '<strong>'. wfMsg( 'youhavenewmessages', $tl, $dl ) . '</strong>'; |
| 1141 | + $s[] = '<strong>' . wfMsg( 'youhavenewmessages', $tl, $dl ) . '</strong>'; |
1074 | 1142 | # disable caching |
1075 | 1143 | $wgOut->setSquidMaxage( 0 ); |
1076 | 1144 | $wgOut->enableClientCache( false ); |
— | — | @@ -1077,9 +1145,11 @@ |
1078 | 1146 | } |
1079 | 1147 | |
1080 | 1148 | $undelete = $this->getUndeleteLink(); |
1081 | | - if( !empty( $undelete ) ) { |
| 1149 | + |
| 1150 | + if ( !empty( $undelete ) ) { |
1082 | 1151 | $s[] = $undelete; |
1083 | 1152 | } |
| 1153 | + |
1084 | 1154 | return $wgLang->pipeList( $s ); |
1085 | 1155 | } |
1086 | 1156 | |
— | — | @@ -1091,12 +1161,14 @@ |
1092 | 1162 | if ( $wgUser->isAllowed( 'deletedhistory' ) && |
1093 | 1163 | ( $this->mTitle->getArticleId() == 0 || $action == 'history' ) ) { |
1094 | 1164 | $n = $this->mTitle->isDeleted(); |
| 1165 | + |
1095 | 1166 | if ( $n ) { |
1096 | 1167 | if ( $wgUser->isAllowed( 'undelete' ) ) { |
1097 | 1168 | $msg = 'thisisdeleted'; |
1098 | 1169 | } else { |
1099 | 1170 | $msg = 'viewdeleted'; |
1100 | 1171 | } |
| 1172 | + |
1101 | 1173 | return wfMsg( |
1102 | 1174 | $msg, |
1103 | 1175 | $this->link( |
— | — | @@ -1109,6 +1181,7 @@ |
1110 | 1182 | ); |
1111 | 1183 | } |
1112 | 1184 | } |
| 1185 | + |
1113 | 1186 | return ''; |
1114 | 1187 | } |
1115 | 1188 | |
— | — | @@ -1122,8 +1195,8 @@ |
1123 | 1196 | $s[] = "<a href=\"$printurl\" rel=\"alternate\">" . wfMsg( 'printableversion' ) . '</a>'; |
1124 | 1197 | } |
1125 | 1198 | |
1126 | | - if( $wgOut->isSyndicated() ) { |
1127 | | - foreach( $wgFeedClasses as $format => $class ) { |
| 1199 | + if ( $wgOut->isSyndicated() ) { |
| 1200 | + foreach ( $wgFeedClasses as $format => $class ) { |
1128 | 1201 | $feedurl = $wgRequest->escapeAppendQuery( "feed=$format" ); |
1129 | 1202 | $s[] = "<a href=\"$feedurl\" rel=\"alternate\" type=\"application/{$format}+xml\"" |
1130 | 1203 | . " class=\"feedlink\">" . wfMsgHtml( "feed-$format" ) . "</a>"; |
— | — | @@ -1146,36 +1219,43 @@ |
1147 | 1220 | global $wgOut; |
1148 | 1221 | |
1149 | 1222 | $sub = $wgOut->getSubtitle(); |
| 1223 | + |
1150 | 1224 | if ( $sub == '' ) { |
1151 | 1225 | global $wgExtraSubtitle; |
1152 | 1226 | $sub = wfMsgExt( 'tagline', 'parsemag' ) . $wgExtraSubtitle; |
1153 | 1227 | } |
| 1228 | + |
1154 | 1229 | $subpages = $this->subPageSubtitle(); |
1155 | 1230 | $sub .= !empty( $subpages ) ? "</p><p class='subpages'>$subpages" : ''; |
1156 | 1231 | $s = "<p class='subtitle'>{$sub}</p>\n"; |
| 1232 | + |
1157 | 1233 | return $s; |
1158 | 1234 | } |
1159 | 1235 | |
1160 | 1236 | function subPageSubtitle() { |
1161 | 1237 | $subpages = ''; |
1162 | | - if( !wfRunHooks( 'SkinSubPageSubtitle', array( &$subpages ) ) ) { |
| 1238 | + |
| 1239 | + if ( !wfRunHooks( 'SkinSubPageSubtitle', array( &$subpages ) ) ) { |
1163 | 1240 | return $subpages; |
1164 | 1241 | } |
1165 | 1242 | |
1166 | 1243 | global $wgOut; |
1167 | | - if( $wgOut->isArticle() && MWNamespace::hasSubpages( $this->mTitle->getNamespace() ) ) { |
| 1244 | + |
| 1245 | + if ( $wgOut->isArticle() && MWNamespace::hasSubpages( $this->mTitle->getNamespace() ) ) { |
1168 | 1246 | $ptext = $this->mTitle->getPrefixedText(); |
1169 | | - if( preg_match( '/\//', $ptext ) ) { |
| 1247 | + if ( preg_match( '/\//', $ptext ) ) { |
1170 | 1248 | $links = explode( '/', $ptext ); |
1171 | 1249 | array_pop( $links ); |
1172 | 1250 | $c = 0; |
1173 | 1251 | $growinglink = ''; |
1174 | 1252 | $display = ''; |
1175 | | - foreach( $links as $link ) { |
| 1253 | + |
| 1254 | + foreach ( $links as $link ) { |
1176 | 1255 | $growinglink .= $link; |
1177 | 1256 | $display .= $link; |
1178 | 1257 | $linkObj = Title::newFromText( $growinglink ); |
1179 | | - if( is_object( $linkObj ) && $linkObj->exists() ) { |
| 1258 | + |
| 1259 | + if ( is_object( $linkObj ) && $linkObj->exists() ) { |
1180 | 1260 | $getlink = $this->link( |
1181 | 1261 | $linkObj, |
1182 | 1262 | htmlspecialchars( $display ), |
— | — | @@ -1183,12 +1263,15 @@ |
1184 | 1264 | array(), |
1185 | 1265 | array( 'known', 'noclasses' ) |
1186 | 1266 | ); |
| 1267 | + |
1187 | 1268 | $c++; |
1188 | | - if( $c > 1 ) { |
| 1269 | + |
| 1270 | + if ( $c > 1 ) { |
1189 | 1271 | $subpages .= wfMsgExt( 'pipe-separator', 'escapenoentities' ); |
1190 | 1272 | } else { |
1191 | 1273 | $subpages .= '< '; |
1192 | 1274 | } |
| 1275 | + |
1193 | 1276 | $subpages .= $getlink; |
1194 | 1277 | $display = ''; |
1195 | 1278 | } else { |
— | — | @@ -1198,6 +1281,7 @@ |
1199 | 1282 | } |
1200 | 1283 | } |
1201 | 1284 | } |
| 1285 | + |
1202 | 1286 | return $subpages; |
1203 | 1287 | } |
1204 | 1288 | |
— | — | @@ -1215,8 +1299,9 @@ |
1216 | 1300 | $logoutPage = $wgContLang->specialPage( 'Userlogout' ); |
1217 | 1301 | |
1218 | 1302 | $ret = ''; |
| 1303 | + |
1219 | 1304 | if ( $wgUser->isAnon() ) { |
1220 | | - if( $this->showIPinHeader() ) { |
| 1305 | + if ( $this->showIPinHeader() ) { |
1221 | 1306 | $name = wfGetIP(); |
1222 | 1307 | |
1223 | 1308 | $talkLink = $this->link( $wgUser->getTalkPage(), |
— | — | @@ -1229,6 +1314,7 @@ |
1230 | 1315 | |
1231 | 1316 | $returnTo = $this->mTitle->getPrefixedDBkey(); |
1232 | 1317 | $query = array(); |
| 1318 | + |
1233 | 1319 | if ( $logoutPage != $returnTo ) { |
1234 | 1320 | $query['returnto'] = $returnTo; |
1235 | 1321 | } |
— | — | @@ -1256,6 +1342,7 @@ |
1257 | 1343 | $this->specialLink( 'preferences' ), |
1258 | 1344 | ) ); |
1259 | 1345 | } |
| 1346 | + |
1260 | 1347 | $ret = $wgLang->pipeList( array( |
1261 | 1348 | $ret, |
1262 | 1349 | $this->link( |
— | — | @@ -1278,6 +1365,7 @@ |
1279 | 1366 | |
1280 | 1367 | function searchForm() { |
1281 | 1368 | global $wgRequest, $wgUseTwoButtonsSearchForm; |
| 1369 | + |
1282 | 1370 | $search = $wgRequest->getText( 'search' ); |
1283 | 1371 | |
1284 | 1372 | $s = '<form id="searchform' . $this->searchboxes . '" name="search" class="inline" method="post" action="' |
— | — | @@ -1286,7 +1374,7 @@ |
1287 | 1375 | . htmlspecialchars( substr( $search, 0, 256 ) ) . "\" />\n" |
1288 | 1376 | . '<input type="submit" name="go" value="' . wfMsg( 'searcharticle' ) . '" />'; |
1289 | 1377 | |
1290 | | - if( $wgUseTwoButtonsSearchForm ) { |
| 1378 | + if ( $wgUseTwoButtonsSearchForm ) { |
1291 | 1379 | $s .= ' <input type="submit" name="fulltext" value="' . wfMsg( 'searchbutton' ) . "\" />\n"; |
1292 | 1380 | } else { |
1293 | 1381 | $s .= ' <a href="' . $this->escapeSearchLink() . '" rel="search">' . wfMsg( 'powersearch-legend' ) . "</a>\n"; |
— | — | @@ -1312,18 +1400,19 @@ |
1313 | 1401 | $s[] = $this->editThisPage(); |
1314 | 1402 | $s[] = $this->historyLink(); |
1315 | 1403 | } |
| 1404 | + |
1316 | 1405 | # Many people don't like this dropdown box |
1317 | | - #$s[] = $this->specialPagesList(); |
| 1406 | + # $s[] = $this->specialPagesList(); |
1318 | 1407 | |
1319 | | - if( $this->variantLinks() ) { |
| 1408 | + if ( $this->variantLinks() ) { |
1320 | 1409 | $s[] = $this->variantLinks(); |
1321 | 1410 | } |
1322 | 1411 | |
1323 | | - if( $this->extensionTabLinks() ) { |
| 1412 | + if ( $this->extensionTabLinks() ) { |
1324 | 1413 | $s[] = $this->extensionTabLinks(); |
1325 | 1414 | } |
1326 | 1415 | |
1327 | | - // FIXME: Is using Language::pipeList impossible here? Do not quite understand the use of the newline |
| 1416 | + // @todo FIXME: Is using Language::pipeList impossible here? Do not quite understand the use of the newline |
1328 | 1417 | return implode( $s, wfMsgExt( 'pipe-separator', 'escapenoentities' ) . "\n" ); |
1329 | 1418 | } |
1330 | 1419 | |
— | — | @@ -1338,13 +1427,13 @@ |
1339 | 1428 | $out = ''; |
1340 | 1429 | $s = array(); |
1341 | 1430 | wfRunHooks( 'SkinTemplateTabs', array( $this, &$tabs ) ); |
1342 | | - foreach( $tabs as $tab ) { |
| 1431 | + foreach ( $tabs as $tab ) { |
1343 | 1432 | $s[] = Xml::element( 'a', |
1344 | 1433 | array( 'href' => $tab['href'] ), |
1345 | 1434 | $tab['text'] ); |
1346 | 1435 | } |
1347 | 1436 | |
1348 | | - if( count( $s ) ) { |
| 1437 | + if ( count( $s ) ) { |
1349 | 1438 | global $wgLang; |
1350 | 1439 | |
1351 | 1440 | $out = wfMsgExt( 'pipe-separator' , 'escapenoentities' ); |
— | — | @@ -1360,13 +1449,17 @@ |
1361 | 1450 | */ |
1362 | 1451 | function variantLinks() { |
1363 | 1452 | $s = ''; |
| 1453 | + |
1364 | 1454 | /* show links to different language variants */ |
1365 | 1455 | global $wgDisableLangConversion, $wgLang, $wgContLang; |
| 1456 | + |
1366 | 1457 | $variants = $wgContLang->getVariants(); |
1367 | | - if( !$wgDisableLangConversion && sizeof( $variants ) > 1 ) { |
1368 | | - foreach( $variants as $code ) { |
| 1458 | + |
| 1459 | + if ( !$wgDisableLangConversion && sizeof( $variants ) > 1 ) { |
| 1460 | + foreach ( $variants as $code ) { |
1369 | 1461 | $varname = $wgContLang->getVariantname( $code ); |
1370 | | - if( $varname == 'disable' ) { |
| 1462 | + |
| 1463 | + if ( $varname == 'disable' ) { |
1371 | 1464 | continue; |
1372 | 1465 | } |
1373 | 1466 | $s = $wgLang->pipeList( array( |
— | — | @@ -1375,6 +1468,7 @@ |
1376 | 1469 | ) ); |
1377 | 1470 | } |
1378 | 1471 | } |
| 1472 | + |
1379 | 1473 | return $s; |
1380 | 1474 | } |
1381 | 1475 | |
— | — | @@ -1385,31 +1479,33 @@ |
1386 | 1480 | $s = ''; |
1387 | 1481 | if ( $wgOut->isArticleRelated() ) { |
1388 | 1482 | $element[] = '<strong>' . $this->editThisPage() . '</strong>'; |
| 1483 | + |
1389 | 1484 | if ( $wgUser->isLoggedIn() ) { |
1390 | 1485 | $element[] = $this->watchThisPage(); |
1391 | 1486 | } |
| 1487 | + |
1392 | 1488 | $element[] = $this->talkLink(); |
1393 | 1489 | $element[] = $this->historyLink(); |
1394 | 1490 | $element[] = $this->whatLinksHere(); |
1395 | 1491 | $element[] = $this->watchPageLinksLink(); |
1396 | 1492 | |
1397 | | - if( $wgUseTrackbacks ) { |
| 1493 | + if ( $wgUseTrackbacks ) { |
1398 | 1494 | $element[] = $this->trackbackLink(); |
1399 | 1495 | } |
1400 | 1496 | |
1401 | 1497 | if ( |
1402 | 1498 | $this->mTitle->getNamespace() == NS_USER || |
1403 | 1499 | $this->mTitle->getNamespace() == NS_USER_TALK |
1404 | | - ) |
1405 | | - { |
| 1500 | + ) { |
1406 | 1501 | $id = User::idFromName( $this->mTitle->getText() ); |
1407 | 1502 | $ip = User::isIP( $this->mTitle->getText() ); |
1408 | 1503 | |
1409 | 1504 | # Both anons and non-anons have contributions list |
1410 | | - if( $id || $ip ) { |
| 1505 | + if ( $id || $ip ) { |
1411 | 1506 | $element[] = $this->userContribsLink(); |
1412 | 1507 | } |
1413 | | - if( $this->showEmailUser( $id ) ) { |
| 1508 | + |
| 1509 | + if ( $this->showEmailUser( $id ) ) { |
1414 | 1510 | $element[] = $this->emailUserLink(); |
1415 | 1511 | } |
1416 | 1512 | } |
— | — | @@ -1418,17 +1514,21 @@ |
1419 | 1515 | |
1420 | 1516 | if ( $this->mTitle->getArticleId() ) { |
1421 | 1517 | $s .= "\n<br />"; |
| 1518 | + |
1422 | 1519 | // Delete/protect/move links for privileged users |
1423 | | - if( $wgUser->isAllowed( 'delete' ) ) { |
| 1520 | + if ( $wgUser->isAllowed( 'delete' ) ) { |
1424 | 1521 | $s .= $this->deleteThisPage(); |
1425 | 1522 | } |
1426 | | - if( $wgUser->isAllowed( 'protect' ) ) { |
| 1523 | + |
| 1524 | + if ( $wgUser->isAllowed( 'protect' ) ) { |
1427 | 1525 | $s .= $sep . $this->protectThisPage(); |
1428 | 1526 | } |
1429 | | - if( $wgUser->isAllowed( 'move' ) ) { |
| 1527 | + |
| 1528 | + if ( $wgUser->isAllowed( 'move' ) ) { |
1430 | 1529 | $s .= $sep . $this->moveThisPage(); |
1431 | 1530 | } |
1432 | 1531 | } |
| 1532 | + |
1433 | 1533 | $s .= "<br />\n" . $this->otherLanguages(); |
1434 | 1534 | } |
1435 | 1535 | |
— | — | @@ -1441,34 +1541,40 @@ |
1442 | 1542 | |
1443 | 1543 | $oldid = $wgRequest->getVal( 'oldid' ); |
1444 | 1544 | $diff = $wgRequest->getVal( 'diff' ); |
| 1545 | + |
1445 | 1546 | if ( !$wgOut->isArticle() ) { |
1446 | 1547 | return ''; |
1447 | 1548 | } |
1448 | | - if( !$wgArticle instanceof Article ) { |
| 1549 | + |
| 1550 | + if ( !$wgArticle instanceof Article ) { |
1449 | 1551 | return ''; |
1450 | 1552 | } |
| 1553 | + |
1451 | 1554 | if ( isset( $oldid ) || isset( $diff ) ) { |
1452 | 1555 | return ''; |
1453 | 1556 | } |
| 1557 | + |
1454 | 1558 | if ( 0 == $wgArticle->getID() ) { |
1455 | 1559 | return ''; |
1456 | 1560 | } |
1457 | 1561 | |
1458 | 1562 | $s = ''; |
| 1563 | + |
1459 | 1564 | if ( !$wgDisableCounters ) { |
1460 | 1565 | $count = $wgLang->formatNum( $wgArticle->getCount() ); |
| 1566 | + |
1461 | 1567 | if ( $count ) { |
1462 | 1568 | $s = wfMsgExt( 'viewcount', array( 'parseinline' ), $count ); |
1463 | 1569 | } |
1464 | 1570 | } |
1465 | 1571 | |
1466 | | - if( $wgMaxCredits != 0 ) { |
| 1572 | + if ( $wgMaxCredits != 0 ) { |
1467 | 1573 | $s .= ' ' . Credits::getCredits( $wgArticle, $wgMaxCredits, $wgShowCreditsIfMax ); |
1468 | 1574 | } else { |
1469 | 1575 | $s .= $this->lastModified(); |
1470 | 1576 | } |
1471 | 1577 | |
1472 | | - if( $wgPageShowWatchingUsers && $wgUser->getOption( 'shownumberswatching' ) ) { |
| 1578 | + if ( $wgPageShowWatchingUsers && $wgUser->getOption( 'shownumberswatching' ) ) { |
1473 | 1579 | $dbr = wfGetDB( DB_SLAVE ); |
1474 | 1580 | $res = $dbr->select( |
1475 | 1581 | 'watchlist', |
— | — | @@ -1495,6 +1601,7 @@ |
1496 | 1602 | if ( $type == 'detect' ) { |
1497 | 1603 | $diff = $wgRequest->getVal( 'diff' ); |
1498 | 1604 | $isCur = $wgArticle && $wgArticle->isCurrent(); |
| 1605 | + |
1499 | 1606 | if ( is_null( $diff ) && !$isCur && wfMsgForContent( 'history_copyright' ) !== '-' ) { |
1500 | 1607 | $type = 'history'; |
1501 | 1608 | } else { |
— | — | @@ -1509,20 +1616,23 @@ |
1510 | 1617 | } |
1511 | 1618 | |
1512 | 1619 | $out = ''; |
1513 | | - if( $wgRightsPage ) { |
| 1620 | + |
| 1621 | + if ( $wgRightsPage ) { |
1514 | 1622 | $title = Title::newFromText( $wgRightsPage ); |
1515 | 1623 | $link = $this->linkKnown( $title, $wgRightsText ); |
1516 | | - } elseif( $wgRightsUrl ) { |
| 1624 | + } elseif ( $wgRightsUrl ) { |
1517 | 1625 | $link = $this->makeExternalLink( $wgRightsUrl, $wgRightsText ); |
1518 | | - } elseif( $wgRightsText ) { |
| 1626 | + } elseif ( $wgRightsText ) { |
1519 | 1627 | $link = $wgRightsText; |
1520 | 1628 | } else { |
1521 | 1629 | # Give up now |
1522 | 1630 | return $out; |
1523 | 1631 | } |
| 1632 | + |
1524 | 1633 | // Allow for site and per-namespace customization of copyright notice. |
1525 | 1634 | $forContent = true; |
1526 | | - if( isset( $wgArticle ) ) { |
| 1635 | + |
| 1636 | + if ( isset( $wgArticle ) ) { |
1527 | 1637 | wfRunHooks( 'SkinCopyrightFooter', array( $wgArticle->getTitle(), $type, &$msg, &$link, &$forContent ) ); |
1528 | 1638 | } |
1529 | 1639 | |
— | — | @@ -1531,26 +1641,33 @@ |
1532 | 1642 | } else { |
1533 | 1643 | $out .= wfMsg( $msg, $link ); |
1534 | 1644 | } |
| 1645 | + |
1535 | 1646 | return $out; |
1536 | 1647 | } |
1537 | 1648 | |
1538 | 1649 | function getCopyrightIcon() { |
1539 | 1650 | global $wgRightsUrl, $wgRightsText, $wgRightsIcon, $wgCopyrightIcon; |
| 1651 | + |
1540 | 1652 | $out = ''; |
| 1653 | + |
1541 | 1654 | if ( isset( $wgCopyrightIcon ) && $wgCopyrightIcon ) { |
1542 | 1655 | $out = $wgCopyrightIcon; |
1543 | 1656 | } elseif ( $wgRightsIcon ) { |
1544 | 1657 | $icon = htmlspecialchars( $wgRightsIcon ); |
| 1658 | + |
1545 | 1659 | if ( $wgRightsUrl ) { |
1546 | 1660 | $url = htmlspecialchars( $wgRightsUrl ); |
1547 | | - $out .= '<a href="'.$url.'">'; |
| 1661 | + $out .= '<a href="' . $url . '">'; |
1548 | 1662 | } |
| 1663 | + |
1549 | 1664 | $text = htmlspecialchars( $wgRightsText ); |
1550 | 1665 | $out .= "<img src=\"$icon\" alt=\"$text\" width=\"88\" height=\"31\" />"; |
| 1666 | + |
1551 | 1667 | if ( $wgRightsUrl ) { |
1552 | 1668 | $out .= '</a>'; |
1553 | 1669 | } |
1554 | 1670 | } |
| 1671 | + |
1555 | 1672 | return $out; |
1556 | 1673 | } |
1557 | 1674 | |
— | — | @@ -1560,18 +1677,22 @@ |
1561 | 1678 | */ |
1562 | 1679 | function getPoweredBy() { |
1563 | 1680 | global $wgStylePath; |
| 1681 | + |
1564 | 1682 | $url = htmlspecialchars( "$wgStylePath/common/images/poweredby_mediawiki_88x31.png" ); |
1565 | 1683 | $img = '<a href="http://www.mediawiki.org/"><img src="' . $url . '" height="31" width="88" alt="Powered by MediaWiki" /></a>'; |
| 1684 | + |
1566 | 1685 | return $img; |
1567 | 1686 | } |
1568 | 1687 | |
1569 | 1688 | function lastModified() { |
1570 | 1689 | global $wgLang, $wgArticle; |
1571 | | - if( $this->mRevisionId && $this->mRevisionId != $wgArticle->getLatest() ) { |
| 1690 | + |
| 1691 | + if ( $this->mRevisionId && $this->mRevisionId != $wgArticle->getLatest() ) { |
1572 | 1692 | $timestamp = Revision::getTimestampFromId( $wgArticle->getTitle(), $this->mRevisionId ); |
1573 | 1693 | } else { |
1574 | 1694 | $timestamp = $wgArticle->getTimestamp(); |
1575 | 1695 | } |
| 1696 | + |
1576 | 1697 | if ( $timestamp ) { |
1577 | 1698 | $d = $wgLang->date( $timestamp, true ); |
1578 | 1699 | $t = $wgLang->time( $timestamp, true ); |
— | — | @@ -1579,9 +1700,11 @@ |
1580 | 1701 | } else { |
1581 | 1702 | $s = ''; |
1582 | 1703 | } |
| 1704 | + |
1583 | 1705 | if ( wfGetLB()->getLaggedSlaveMode() ) { |
1584 | 1706 | $s .= ' <strong>' . wfMsg( 'laggedslavemode' ) . '</strong>'; |
1585 | 1707 | } |
| 1708 | + |
1586 | 1709 | return $s; |
1587 | 1710 | } |
1588 | 1711 | |
— | — | @@ -1598,6 +1721,7 @@ |
1599 | 1722 | |
1600 | 1723 | $logourl = $this->getLogo(); |
1601 | 1724 | $s = "<a href='{$url}'><img{$a} src='{$logourl}' alt='[{$mp}]' /></a>"; |
| 1725 | + |
1602 | 1726 | return $s; |
1603 | 1727 | } |
1604 | 1728 | |
— | — | @@ -1606,7 +1730,9 @@ |
1607 | 1731 | */ |
1608 | 1732 | function specialPagesList() { |
1609 | 1733 | global $wgContLang, $wgServer, $wgRedirectScript; |
| 1734 | + |
1610 | 1735 | $pages = array_merge( SpecialPage::getRegularPages(), SpecialPage::getRestrictedPages() ); |
| 1736 | + |
1611 | 1737 | foreach ( $pages as $name => $page ) { |
1612 | 1738 | $pages[$name] = $page->getDescription(); |
1613 | 1739 | } |
— | — | @@ -1625,9 +1751,11 @@ |
1626 | 1752 | $p = $wgContLang->specialPage( $name ); |
1627 | 1753 | $s .= "<option value=\"{$p}\">{$desc}</option>\n"; |
1628 | 1754 | } |
| 1755 | + |
1629 | 1756 | $s .= "</select>\n"; |
1630 | 1757 | $s .= "<input type='submit' value=\"{$go}\" name='redirect' />\n"; |
1631 | 1758 | $s .= "</form>\n"; |
| 1759 | + |
1632 | 1760 | return $s; |
1633 | 1761 | } |
1634 | 1762 | |
— | — | @@ -1643,12 +1771,13 @@ |
1644 | 1772 | array(), |
1645 | 1773 | array( 'known', 'noclasses' ) |
1646 | 1774 | ); |
| 1775 | + |
1647 | 1776 | return $s; |
1648 | 1777 | } |
1649 | 1778 | |
1650 | 1779 | private function footerLink( $desc, $page ) { |
1651 | 1780 | // if the link description has been set to "-" in the default language, |
1652 | | - if ( wfMsgForContent( $desc ) == '-') { |
| 1781 | + if ( wfMsgForContent( $desc ) == '-' ) { |
1653 | 1782 | // then it is disabled, for all languages. |
1654 | 1783 | return ''; |
1655 | 1784 | } else { |
— | — | @@ -1656,6 +1785,7 @@ |
1657 | 1786 | // language (which may or may not be the same as the default language), |
1658 | 1787 | // but we make the link target be the one site-wide page. |
1659 | 1788 | $title = Title::newFromText( wfMsgForContent( $page ) ); |
| 1789 | + |
1660 | 1790 | return $this->linkKnown( |
1661 | 1791 | $title, |
1662 | 1792 | wfMsgExt( $desc, array( 'parsemag', 'escapenoentities' ) ) |
— | — | @@ -1690,9 +1820,9 @@ |
1691 | 1821 | if ( !$wgOut->isArticleRelated() ) { |
1692 | 1822 | $s = wfMsg( 'protectedpage' ); |
1693 | 1823 | } else { |
1694 | | - if( $this->mTitle->quickUserCan( 'edit' ) && $this->mTitle->exists() ) { |
| 1824 | + if ( $this->mTitle->quickUserCan( 'edit' ) && $this->mTitle->exists() ) { |
1695 | 1825 | $t = wfMsg( 'editthispage' ); |
1696 | | - } elseif( $this->mTitle->quickUserCan( 'create' ) && !$this->mTitle->exists() ) { |
| 1826 | + } elseif ( $this->mTitle->quickUserCan( 'create' ) && !$this->mTitle->exists() ) { |
1697 | 1827 | $t = wfMsg( 'create-this-page' ); |
1698 | 1828 | } else { |
1699 | 1829 | $t = wfMsg( 'viewsource' ); |
— | — | @@ -1706,6 +1836,7 @@ |
1707 | 1837 | array( 'known', 'noclasses' ) |
1708 | 1838 | ); |
1709 | 1839 | } |
| 1840 | + |
1710 | 1841 | return $s; |
1711 | 1842 | } |
1712 | 1843 | |
— | — | @@ -1721,7 +1852,7 @@ |
1722 | 1853 | |
1723 | 1854 | $options = array( 'action' => 'edit' ); |
1724 | 1855 | |
1725 | | - if( $this->mRevisionId && ! $wgArticle->isCurrent() ) { |
| 1856 | + if ( $this->mRevisionId && ! $wgArticle->isCurrent() ) { |
1726 | 1857 | $options['oldid'] = intval( $this->mRevisionId ); |
1727 | 1858 | } |
1728 | 1859 | |
— | — | @@ -1732,6 +1863,7 @@ |
1733 | 1864 | global $wgUser, $wgRequest; |
1734 | 1865 | |
1735 | 1866 | $diff = $wgRequest->getVal( 'diff' ); |
| 1867 | + |
1736 | 1868 | if ( $this->mTitle->getArticleId() && ( !$diff ) && $wgUser->isAllowed( 'delete' ) ) { |
1737 | 1869 | $t = wfMsg( 'deletethispage' ); |
1738 | 1870 | |
— | — | @@ -1745,6 +1877,7 @@ |
1746 | 1878 | } else { |
1747 | 1879 | $s = ''; |
1748 | 1880 | } |
| 1881 | + |
1749 | 1882 | return $s; |
1750 | 1883 | } |
1751 | 1884 | |
— | — | @@ -1752,7 +1885,8 @@ |
1753 | 1886 | global $wgUser, $wgRequest; |
1754 | 1887 | |
1755 | 1888 | $diff = $wgRequest->getVal( 'diff' ); |
1756 | | - if ( $this->mTitle->getArticleId() && ( ! $diff ) && $wgUser->isAllowed('protect') ) { |
| 1889 | + |
| 1890 | + if ( $this->mTitle->getArticleId() && ( ! $diff ) && $wgUser->isAllowed( 'protect' ) ) { |
1757 | 1891 | if ( $this->mTitle->isProtected() ) { |
1758 | 1892 | $text = wfMsg( 'unprotectthispage' ); |
1759 | 1893 | $query = array( 'action' => 'unprotect' ); |
— | — | @@ -1771,6 +1905,7 @@ |
1772 | 1906 | } else { |
1773 | 1907 | $s = ''; |
1774 | 1908 | } |
| 1909 | + |
1775 | 1910 | return $s; |
1776 | 1911 | } |
1777 | 1912 | |
— | — | @@ -1799,6 +1934,7 @@ |
1800 | 1935 | } else { |
1801 | 1936 | $s = wfMsg( 'notanarticle' ); |
1802 | 1937 | } |
| 1938 | + |
1803 | 1939 | return $s; |
1804 | 1940 | } |
1805 | 1941 | |
— | — | @@ -1865,6 +2001,7 @@ |
1866 | 2002 | |
1867 | 2003 | function watchPageLinksLink() { |
1868 | 2004 | global $wgOut; |
| 2005 | + |
1869 | 2006 | if ( !$wgOut->isArticleRelated() ) { |
1870 | 2007 | return '(' . wfMsg( 'notanarticle' ) . ')'; |
1871 | 2008 | } else { |
— | — | @@ -1891,19 +2028,23 @@ |
1892 | 2029 | } |
1893 | 2030 | |
1894 | 2031 | $a = $wgOut->getLanguageLinks(); |
| 2032 | + |
1895 | 2033 | if ( 0 == count( $a ) ) { |
1896 | 2034 | return ''; |
1897 | 2035 | } |
1898 | 2036 | |
1899 | 2037 | $s = wfMsg( 'otherlanguages' ) . wfMsg( 'colon-separator' ); |
1900 | 2038 | $first = true; |
1901 | | - if( $wgContLang->isRTL() ) { |
| 2039 | + |
| 2040 | + if ( $wgContLang->isRTL() ) { |
1902 | 2041 | $s .= '<span dir="LTR">'; |
1903 | 2042 | } |
1904 | | - foreach( $a as $l ) { |
| 2043 | + |
| 2044 | + foreach ( $a as $l ) { |
1905 | 2045 | if ( !$first ) { |
1906 | 2046 | $s .= wfMsgExt( 'pipe-separator', 'escapenoentities' ); |
1907 | 2047 | } |
| 2048 | + |
1908 | 2049 | $first = false; |
1909 | 2050 | |
1910 | 2051 | $nt = Title::newFromText( $l ); |
— | — | @@ -1914,12 +2055,15 @@ |
1915 | 2056 | if ( $text == '' ) { |
1916 | 2057 | $text = $l; |
1917 | 2058 | } |
| 2059 | + |
1918 | 2060 | $style = $this->getExternalLinkAttributes(); |
1919 | 2061 | $s .= "<a href=\"{$url}\" title=\"{$title}\"{$style}>{$text}</a>"; |
1920 | 2062 | } |
1921 | | - if( $wgContLang->isRTL() ) { |
| 2063 | + |
| 2064 | + if ( $wgContLang->isRTL() ) { |
1922 | 2065 | $s .= '</span>'; |
1923 | 2066 | } |
| 2067 | + |
1924 | 2068 | return $s; |
1925 | 2069 | } |
1926 | 2070 | |
— | — | @@ -1931,7 +2075,7 @@ |
1932 | 2076 | |
1933 | 2077 | $linkOptions = array(); |
1934 | 2078 | |
1935 | | - if( $this->mTitle->isTalkPage() ) { |
| 2079 | + if ( $this->mTitle->isTalkPage() ) { |
1936 | 2080 | $link = $this->mTitle->getSubjectPage(); |
1937 | 2081 | switch( $link->getNamespace() ) { |
1938 | 2082 | case NS_MAIN: |
— | — | @@ -1946,7 +2090,7 @@ |
1947 | 2091 | case NS_FILE: |
1948 | 2092 | $text = wfMsg( 'imagepage' ); |
1949 | 2093 | # Make link known if image exists, even if the desc. page doesn't. |
1950 | | - if( wfFindFile( $link ) ) |
| 2094 | + if ( wfFindFile( $link ) ) |
1951 | 2095 | $linkOptions[] = 'known'; |
1952 | 2096 | break; |
1953 | 2097 | case NS_MEDIAWIKI: |
— | — | @@ -1984,9 +2128,9 @@ |
1985 | 2129 | # __NEWSECTIONLINK___ changes behaviour here |
1986 | 2130 | # If it is present, the link points to this page, otherwise |
1987 | 2131 | # it points to the talk page |
1988 | | - if( $this->mTitle->isTalkPage() ) { |
| 2132 | + if ( $this->mTitle->isTalkPage() ) { |
1989 | 2133 | $title = $this->mTitle; |
1990 | | - } elseif( $wgOut->showNewSectionLink() ) { |
| 2134 | + } elseif ( $wgOut->showNewSectionLink() ) { |
1991 | 2135 | $title = $this->mTitle; |
1992 | 2136 | } else { |
1993 | 2137 | $title = $this->mTitle->getTalkPage(); |
— | — | @@ -2007,12 +2151,12 @@ |
2008 | 2152 | function getUploadLink() { |
2009 | 2153 | global $wgUploadNavigationUrl; |
2010 | 2154 | |
2011 | | - if( $wgUploadNavigationUrl ) { |
| 2155 | + if ( $wgUploadNavigationUrl ) { |
2012 | 2156 | # Using an empty class attribute to avoid automatic setting of "external" class |
2013 | | - return $this->makeExternalLink( $wgUploadNavigationUrl, wfMsgHtml( 'upload' ), false, null, array( 'class' => '') ); |
| 2157 | + return $this->makeExternalLink( $wgUploadNavigationUrl, wfMsgHtml( 'upload' ), false, null, array( 'class' => '' ) ); |
2014 | 2158 | } else { |
2015 | 2159 | return $this->link( |
2016 | | - SpecialPage::getTitleFor('Upload'), |
| 2160 | + SpecialPage::getTitleFor( 'Upload' ), |
2017 | 2161 | wfMsgHtml( 'upload' ), |
2018 | 2162 | array(), |
2019 | 2163 | array(), |
— | — | @@ -2025,6 +2169,7 @@ |
2026 | 2170 | static function makeMainPageUrl( $urlaction = '' ) { |
2027 | 2171 | $title = Title::newMainPage(); |
2028 | 2172 | self::checkTitle( $title, '' ); |
| 2173 | + |
2029 | 2174 | return $title->getLocalURL( $urlaction ); |
2030 | 2175 | } |
2031 | 2176 | |
— | — | @@ -2047,6 +2192,7 @@ |
2048 | 2193 | static function makeUrl( $name, $urlaction = '' ) { |
2049 | 2194 | $title = Title::newFromText( $name ); |
2050 | 2195 | self::checkTitle( $title, $name ); |
| 2196 | + |
2051 | 2197 | return $title->getLocalURL( $urlaction ); |
2052 | 2198 | } |
2053 | 2199 | |
— | — | @@ -2066,6 +2212,7 @@ |
2067 | 2213 | static function makeNSUrl( $name, $urlaction = '', $namespace = NS_MAIN ) { |
2068 | 2214 | $title = Title::makeTitleSafe( $namespace, $name ); |
2069 | 2215 | self::checkTitle( $title, $name ); |
| 2216 | + |
2070 | 2217 | return $title->getLocalURL( $urlaction ); |
2071 | 2218 | } |
2072 | 2219 | |
— | — | @@ -2073,6 +2220,7 @@ |
2074 | 2221 | static function makeUrlDetails( $name, $urlaction = '' ) { |
2075 | 2222 | $title = Title::newFromText( $name ); |
2076 | 2223 | self::checkTitle( $title, $name ); |
| 2224 | + |
2077 | 2225 | return array( |
2078 | 2226 | 'href' => $title->getLocalURL( $urlaction ), |
2079 | 2227 | 'exists' => $title->getArticleID() != 0 ? true : false |
— | — | @@ -2085,6 +2233,7 @@ |
2086 | 2234 | static function makeKnownUrlDetails( $name, $urlaction = '' ) { |
2087 | 2235 | $title = Title::newFromText( $name ); |
2088 | 2236 | self::checkTitle( $title, $name ); |
| 2237 | + |
2089 | 2238 | return array( |
2090 | 2239 | 'href' => $title->getLocalURL( $urlaction ), |
2091 | 2240 | 'exists' => true |
— | — | @@ -2093,9 +2242,9 @@ |
2094 | 2243 | |
2095 | 2244 | # make sure we have some title to operate on |
2096 | 2245 | static function checkTitle( &$title, $name ) { |
2097 | | - if( !is_object( $title ) ) { |
| 2246 | + if ( !is_object( $title ) ) { |
2098 | 2247 | $title = Title::newFromText( $name ); |
2099 | | - if( !is_object( $title ) ) { |
| 2248 | + if ( !is_object( $title ) ) { |
2100 | 2249 | $title = Title::newFromText( '--error: link target missing--' ); |
2101 | 2250 | } |
2102 | 2251 | } |
— | — | @@ -2128,6 +2277,7 @@ |
2129 | 2278 | if ( $wgEnableSidebarCache ) { |
2130 | 2279 | $parserMemc->set( $key, $bar, $wgSidebarCacheExpiry ); |
2131 | 2280 | } |
| 2281 | + |
2132 | 2282 | wfProfileOut( __METHOD__ ); |
2133 | 2283 | return $bar; |
2134 | 2284 | } |
— | — | @@ -2155,29 +2305,35 @@ |
2156 | 2306 | $wikiBar = array(); # We need to handle the wikitext on a different variable, to avoid trying to do an array operation on text, which would be a fatal error. |
2157 | 2307 | |
2158 | 2308 | $heading = ''; |
2159 | | - foreach( $lines as $line ) { |
2160 | | - if( strpos( $line, '*' ) !== 0 ) { |
| 2309 | + |
| 2310 | + foreach ( $lines as $line ) { |
| 2311 | + if ( strpos( $line, '*' ) !== 0 ) { |
2161 | 2312 | continue; |
2162 | 2313 | } |
2163 | | - if( strpos( $line, '**') !== 0 ) { |
| 2314 | + |
| 2315 | + if ( strpos( $line, '**' ) !== 0 ) { |
2164 | 2316 | $heading = trim( $line, '* ' ); |
2165 | | - if( !array_key_exists( $heading, $bar ) ) { |
| 2317 | + if ( !array_key_exists( $heading, $bar ) ) { |
2166 | 2318 | $bar[$heading] = array(); |
2167 | 2319 | } |
2168 | 2320 | } else { |
2169 | 2321 | $line = trim( $line, '* ' ); |
2170 | | - if( strpos( $line, '|' ) !== false ) { // sanity check |
| 2322 | + |
| 2323 | + if ( strpos( $line, '|' ) !== false ) { // sanity check |
2171 | 2324 | $line = array_map( 'trim', explode( '|', $line, 2 ) ); |
2172 | 2325 | $link = wfMsgForContent( $line[0] ); |
2173 | | - if( $link == '-' ) { |
| 2326 | + |
| 2327 | + if ( $link == '-' ) { |
2174 | 2328 | continue; |
2175 | 2329 | } |
2176 | 2330 | |
2177 | 2331 | $text = wfMsgExt( $line[1], 'parsemag' ); |
2178 | | - if( wfEmptyMsg( $line[1], $text ) ) { |
| 2332 | + |
| 2333 | + if ( wfEmptyMsg( $line[1], $text ) ) { |
2179 | 2334 | $text = $line[1]; |
2180 | 2335 | } |
2181 | | - if( wfEmptyMsg( $line[0], $link ) ) { |
| 2336 | + |
| 2337 | + if ( wfEmptyMsg( $line[0], $link ) ) { |
2182 | 2338 | $link = $line[0]; |
2183 | 2339 | } |
2184 | 2340 | |
— | — | @@ -2185,6 +2341,7 @@ |
2186 | 2342 | $href = $link; |
2187 | 2343 | } else { |
2188 | 2344 | $title = Title::newFromText( $link ); |
| 2345 | + |
2189 | 2346 | if ( $title ) { |
2190 | 2347 | $title = $title->fixSpecialName(); |
2191 | 2348 | $href = $title->getLocalURL(); |
— | — | @@ -2199,15 +2356,16 @@ |
2200 | 2357 | 'id' => 'n-' . strtr( $line[1], ' ', '-' ), |
2201 | 2358 | 'active' => false |
2202 | 2359 | ); |
2203 | | - } else if ( (substr($line, 0, 2) == '{{') && (substr($line, -2) == '}}') ) { |
| 2360 | + } else if ( ( substr( $line, 0, 2 ) == '{{' ) && ( substr( $line, -2 ) == '}}' ) ) { |
2204 | 2361 | global $wgParser, $wgTitle; |
2205 | 2362 | |
2206 | | - $line = substr($line, 2, strlen($line) - 4 ); |
| 2363 | + $line = substr( $line, 2, strlen( $line ) - 4 ); |
2207 | 2364 | |
2208 | | - if (is_null($wgParser->mOptions)) |
| 2365 | + if ( is_null( $wgParser->mOptions ) ) { |
2209 | 2366 | $wgParser->mOptions = new ParserOptions(); |
| 2367 | + } |
2210 | 2368 | |
2211 | | - $wgParser->mOptions->setEditSection(false); |
| 2369 | + $wgParser->mOptions->setEditSection( false ); |
2212 | 2370 | $wikiBar[$heading] = $wgParser->parse( wfMsgForContentNoTrans( $line ) , $wgTitle, $wgParser->mOptions )->getText(); |
2213 | 2371 | } else { |
2214 | 2372 | continue; |
— | — | @@ -2215,8 +2373,9 @@ |
2216 | 2374 | } |
2217 | 2375 | } |
2218 | 2376 | |
2219 | | - if ( count($wikiBar) > 0 ) |
2220 | | - $bar = array_merge($bar, $wikiBar); |
| 2377 | + if ( count( $wikiBar ) > 0 ) { |
| 2378 | + $bar = array_merge( $bar, $wikiBar ); |
| 2379 | + } |
2221 | 2380 | |
2222 | 2381 | return $bar; |
2223 | 2382 | } |
— | — | @@ -2239,14 +2398,15 @@ |
2240 | 2399 | */ |
2241 | 2400 | function getNewtalks() { |
2242 | 2401 | global $wgUser, $wgOut; |
| 2402 | + |
2243 | 2403 | $newtalks = $wgUser->getNewMessageLinks(); |
2244 | 2404 | $ntl = ''; |
2245 | 2405 | |
2246 | | - if( count( $newtalks ) == 1 && $newtalks[0]['wiki'] === wfWikiID() ) { |
| 2406 | + if ( count( $newtalks ) == 1 && $newtalks[0]['wiki'] === wfWikiID() ) { |
2247 | 2407 | $userTitle = $this->mUser->getUserPage(); |
2248 | 2408 | $userTalkTitle = $userTitle->getTalkPage(); |
2249 | 2409 | |
2250 | | - if( !$userTalkTitle->equals( $this->mTitle ) ) { |
| 2410 | + if ( !$userTalkTitle->equals( $this->mTitle ) ) { |
2251 | 2411 | $newMessagesLink = $this->link( |
2252 | 2412 | $userTalkTitle, |
2253 | 2413 | wfMsgHtml( 'newmessageslink' ), |
— | — | @@ -2271,11 +2431,12 @@ |
2272 | 2432 | # Disable Squid cache |
2273 | 2433 | $wgOut->setSquidMaxage( 0 ); |
2274 | 2434 | } |
2275 | | - } elseif( count( $newtalks ) ) { |
| 2435 | + } elseif ( count( $newtalks ) ) { |
2276 | 2436 | // _>" " for BC <= 1.16 |
2277 | 2437 | $sep = str_replace( '_', ' ', wfMsgHtml( 'newtalkseparator' ) ); |
2278 | 2438 | $msgs = array(); |
2279 | | - foreach( $newtalks as $newtalk ) { |
| 2439 | + |
| 2440 | + foreach ( $newtalks as $newtalk ) { |
2280 | 2441 | $msgs[] = Xml::element( |
2281 | 2442 | 'a', |
2282 | 2443 | array( 'href' => $newtalk['link'] ), $newtalk['wiki'] |
— | — | @@ -2285,7 +2446,7 @@ |
2286 | 2447 | $ntl = wfMsgHtml( 'youhavenewmessagesmulti', $parts ); |
2287 | 2448 | $wgOut->setSquidMaxage( 0 ); |
2288 | 2449 | } |
| 2450 | + |
2289 | 2451 | return $ntl; |
2290 | 2452 | } |
2291 | | - |
2292 | 2453 | } |
Index: trunk/phase3/includes/Exception.php |
— | — | @@ -32,11 +32,13 @@ |
33 | 33 | */ |
34 | 34 | function useMessageCache() { |
35 | 35 | global $wgLang; |
| 36 | + |
36 | 37 | foreach ( $this->getTrace() as $frame ) { |
37 | 38 | if ( isset( $frame['class'] ) && $frame['class'] === 'LocalisationCache' ) { |
38 | 39 | return false; |
39 | 40 | } |
40 | 41 | } |
| 42 | + |
41 | 43 | return is_object( $wgLang ); |
42 | 44 | } |
43 | 45 | |
— | — | @@ -49,20 +51,26 @@ |
50 | 52 | */ |
51 | 53 | function runHooks( $name, $args = array() ) { |
52 | 54 | global $wgExceptionHooks; |
53 | | - if( !isset( $wgExceptionHooks ) || !is_array( $wgExceptionHooks ) ) |
| 55 | + |
| 56 | + if ( !isset( $wgExceptionHooks ) || !is_array( $wgExceptionHooks ) ) { |
54 | 57 | return; // Just silently ignore |
55 | | - if( !array_key_exists( $name, $wgExceptionHooks ) || !is_array( $wgExceptionHooks[ $name ] ) ) |
| 58 | + } |
| 59 | + |
| 60 | + if ( !array_key_exists( $name, $wgExceptionHooks ) || !is_array( $wgExceptionHooks[ $name ] ) ) { |
56 | 61 | return; |
| 62 | + } |
| 63 | + |
57 | 64 | $hooks = $wgExceptionHooks[ $name ]; |
58 | 65 | $callargs = array_merge( array( $this ), $args ); |
59 | 66 | |
60 | | - foreach( $hooks as $hook ) { |
61 | | - if( is_string( $hook ) || ( is_array( $hook ) && count( $hook ) >= 2 && is_string( $hook[0] ) ) ) { //'function' or array( 'class', hook' ) |
| 67 | + foreach ( $hooks as $hook ) { |
| 68 | + if ( is_string( $hook ) || ( is_array( $hook ) && count( $hook ) >= 2 && is_string( $hook[0] ) ) ) { // 'function' or array( 'class', hook' ) |
62 | 69 | $result = call_user_func_array( $hook, $callargs ); |
63 | 70 | } else { |
64 | 71 | $result = null; |
65 | 72 | } |
66 | | - if( is_string( $result ) ) |
| 73 | + |
| 74 | + if ( is_string( $result ) ) |
67 | 75 | return $result; |
68 | 76 | } |
69 | 77 | } |
— | — | @@ -78,6 +86,7 @@ |
79 | 87 | */ |
80 | 88 | function msg( $key, $fallback /*[, params...] */ ) { |
81 | 89 | $args = array_slice( func_get_args(), 2 ); |
| 90 | + |
82 | 91 | if ( $this->useMessageCache() ) { |
83 | 92 | return wfMsgReal( $key, $args ); |
84 | 93 | } else { |
— | — | @@ -94,7 +103,8 @@ |
95 | 104 | */ |
96 | 105 | function getHTML() { |
97 | 106 | global $wgShowExceptionDetails; |
98 | | - if( $wgShowExceptionDetails ) { |
| 107 | + |
| 108 | + if ( $wgShowExceptionDetails ) { |
99 | 109 | return '<p>' . nl2br( htmlspecialchars( $this->getMessage() ) ) . |
100 | 110 | '</p><p>Backtrace:</p><p>' . nl2br( htmlspecialchars( $this->getTraceAsString() ) ) . |
101 | 111 | "</p>\n"; |
— | — | @@ -111,7 +121,8 @@ |
112 | 122 | */ |
113 | 123 | function getText() { |
114 | 124 | global $wgShowExceptionDetails; |
115 | | - if( $wgShowExceptionDetails ) { |
| 125 | + |
| 126 | + if ( $wgShowExceptionDetails ) { |
116 | 127 | return $this->getMessage() . |
117 | 128 | "\nBacktrace:\n" . $this->getTraceAsString() . "\n"; |
118 | 129 | } else { |
— | — | @@ -126,6 +137,7 @@ |
127 | 138 | return wfMsg( 'internalerror' ); |
128 | 139 | } else { |
129 | 140 | global $wgSitename; |
| 141 | + |
130 | 142 | return "$wgSitename error"; |
131 | 143 | } |
132 | 144 | } |
— | — | @@ -138,9 +150,11 @@ |
139 | 151 | */ |
140 | 152 | function getLogMessage() { |
141 | 153 | global $wgRequest; |
| 154 | + |
142 | 155 | $file = $this->getFile(); |
143 | 156 | $line = $this->getLine(); |
144 | 157 | $message = $this->getMessage(); |
| 158 | + |
145 | 159 | if ( isset( $wgRequest ) ) { |
146 | 160 | $url = $wgRequest->getRequestURL(); |
147 | 161 | if ( !$url ) { |
— | — | @@ -156,6 +170,7 @@ |
157 | 171 | /** Output the exception report using HTML */ |
158 | 172 | function reportHTML() { |
159 | 173 | global $wgOut; |
| 174 | + |
160 | 175 | if ( $this->useOutputPage() ) { |
161 | 176 | $wgOut->setPageTitle( $this->getPageTitle() ); |
162 | 177 | $wgOut->setRobotPolicy( "noindex,nofollow" ); |
— | — | @@ -163,16 +178,19 @@ |
164 | 179 | $wgOut->enableClientCache( false ); |
165 | 180 | $wgOut->redirect( '' ); |
166 | 181 | $wgOut->clearHTML(); |
167 | | - if( $hookResult = $this->runHooks( get_class( $this ) ) ) { |
| 182 | + |
| 183 | + if ( $hookResult = $this->runHooks( get_class( $this ) ) ) { |
168 | 184 | $wgOut->addHTML( $hookResult ); |
169 | 185 | } else { |
170 | 186 | $wgOut->addHTML( $this->getHTML() ); |
171 | 187 | } |
| 188 | + |
172 | 189 | $wgOut->output(); |
173 | 190 | } else { |
174 | | - if( $hookResult = $this->runHooks( get_class( $this ) . "Raw" ) ) { |
| 191 | + if ( $hookResult = $this->runHooks( get_class( $this ) . "Raw" ) ) { |
175 | 192 | die( $hookResult ); |
176 | 193 | } |
| 194 | + |
177 | 195 | if ( defined( 'MEDIAWIKI_INSTALL' ) || $this->htmlBodyOnly() ) { |
178 | 196 | echo $this->getHTML(); |
179 | 197 | } else { |
— | — | @@ -189,9 +207,11 @@ |
190 | 208 | */ |
191 | 209 | function report() { |
192 | 210 | $log = $this->getLogMessage(); |
| 211 | + |
193 | 212 | if ( $log ) { |
194 | 213 | wfDebugLog( 'exception', $log ); |
195 | 214 | } |
| 215 | + |
196 | 216 | if ( self::isCommandLine() ) { |
197 | 217 | wfPrintError( $this->getText() ); |
198 | 218 | } else { |
— | — | @@ -208,11 +228,12 @@ |
209 | 229 | |
210 | 230 | if ( !headers_sent() ) { |
211 | 231 | header( 'HTTP/1.0 500 Internal Server Error' ); |
212 | | - header( 'Content-type: text/html; charset='.$wgOutputEncoding ); |
| 232 | + header( 'Content-type: text/html; charset=' . $wgOutputEncoding ); |
213 | 233 | /* Don't cache error pages! They cause no end of trouble... */ |
214 | 234 | header( 'Cache-control: none' ); |
215 | 235 | header( 'Pragma: nocache' ); |
216 | 236 | } |
| 237 | + |
217 | 238 | $title = $this->getPageTitle(); |
218 | 239 | return "<html> |
219 | 240 | <head> |
— | — | @@ -274,6 +295,7 @@ |
275 | 296 | |
276 | 297 | function report() { |
277 | 298 | global $wgOut; |
| 299 | + |
278 | 300 | $wgOut->showErrorPage( $this->title, $this->msg ); |
279 | 301 | $wgOut->output(); |
280 | 302 | } |
— | — | @@ -293,6 +315,7 @@ |
294 | 316 | global $wgShowExceptionDetails; |
295 | 317 | |
296 | 318 | $cmdLine = MWException::isCommandLine(); |
| 319 | + |
297 | 320 | if ( $e instanceof MWException ) { |
298 | 321 | try { |
299 | 322 | $e->report(); |
— | — | @@ -301,6 +324,7 @@ |
302 | 325 | // Show a simpler error message for the original exception, |
303 | 326 | // don't try to invoke report() |
304 | 327 | $message = "MediaWiki internal error.\n\n"; |
| 328 | + |
305 | 329 | if ( $wgShowExceptionDetails ) { |
306 | 330 | $message .= 'Original exception: ' . $e->__toString() . "\n\n" . |
307 | 331 | 'Exception caught inside exception handler: ' . $e2->__toString(); |
— | — | @@ -309,23 +333,27 @@ |
310 | 334 | "Set \$wgShowExceptionDetails = true; at the bottom of LocalSettings.php " . |
311 | 335 | "to show detailed debugging information."; |
312 | 336 | } |
| 337 | + |
313 | 338 | $message .= "\n"; |
| 339 | + |
314 | 340 | if ( $cmdLine ) { |
315 | 341 | wfPrintError( $message ); |
316 | 342 | } else { |
317 | | - echo nl2br( htmlspecialchars( $message ) ). "\n"; |
| 343 | + echo nl2br( htmlspecialchars( $message ) ) . "\n"; |
318 | 344 | } |
319 | 345 | } |
320 | 346 | } else { |
321 | 347 | $message = "Unexpected non-MediaWiki exception encountered, of type \"" . get_class( $e ) . "\"\n" . |
322 | 348 | $e->__toString() . "\n"; |
| 349 | + |
323 | 350 | if ( $wgShowExceptionDetails ) { |
324 | | - $message .= "\n" . $e->getTraceAsString() ."\n"; |
| 351 | + $message .= "\n" . $e->getTraceAsString() . "\n"; |
325 | 352 | } |
| 353 | + |
326 | 354 | if ( $cmdLine ) { |
327 | 355 | wfPrintError( $message ); |
328 | 356 | } else { |
329 | | - echo nl2br( htmlspecialchars( $message ) ). "\n"; |
| 357 | + echo nl2br( htmlspecialchars( $message ) ) . "\n"; |
330 | 358 | } |
331 | 359 | } |
332 | 360 | } |
— | — | @@ -335,7 +363,7 @@ |
336 | 364 | * Use this in command line mode only (see isCommandLine) |
337 | 365 | */ |
338 | 366 | function wfPrintError( $message ) { |
339 | | - #NOTE: STDERR may not be available, especially if php-cgi is used from the command line (bug #15602). |
| 367 | + # NOTE: STDERR may not be available, especially if php-cgi is used from the command line (bug #15602). |
340 | 368 | # Try to produce meaningful output anyway. Using echo may corrupt output to STDOUT though. |
341 | 369 | if ( defined( 'STDERR' ) ) { |
342 | 370 | fwrite( STDERR, $message ); |
— | — | @@ -357,6 +385,7 @@ |
358 | 386 | */ |
359 | 387 | function wfExceptionHandler( $e ) { |
360 | 388 | global $wgFullyInitialised; |
| 389 | + |
361 | 390 | wfReportException( $e ); |
362 | 391 | |
363 | 392 | // Final cleanup, similar to wfErrorExit() |