Index: branches/REL1_18/extensions/LiquidThreads/classes/ParserFunctions.php |
— | — | @@ -36,8 +36,8 @@ |
37 | 37 | $title = $parser->getTitle(); |
38 | 38 | } |
39 | 39 | |
40 | | - $talkpage = new Article( $title ); |
41 | | - $article = new Article( $parser->getTitle() ); |
| 40 | + $talkpage = new Article( $title, 0 ); |
| 41 | + $article = new Article( $parser->getTitle(), 0 ); |
42 | 42 | |
43 | 43 | $data = array( |
44 | 44 | 'type' => 'talkpage', |
— | — | @@ -69,7 +69,7 @@ |
70 | 70 | if ( is_numeric( $args['thread'] ) ) { |
71 | 71 | $thread = Threads::withId( $args['thread'] ); |
72 | 72 | } elseif ( $title ) { |
73 | | - $article = new Article( $title ); |
| 73 | + $article = new Article( $title, 0 ); |
74 | 74 | $thread = Threads::withRoot( $article ); |
75 | 75 | } |
76 | 76 | } |
— | — | @@ -135,7 +135,7 @@ |
136 | 136 | $oldOut = $wgOut->getHTML(); |
137 | 137 | $wgOut->clearHTML(); |
138 | 138 | |
139 | | - $root = new Article( $title ); |
| 139 | + $root = new Article( $title, 0 ); |
140 | 140 | $thread = Threads::withRoot( $root ); |
141 | 141 | |
142 | 142 | $view = new LqtView( $wgOut, $article, $title, $wgUser, $wgRequest ); |
Index: branches/REL1_18/extensions/Checkpoint/Checkpoint.php |
— | — | @@ -45,7 +45,7 @@ |
46 | 46 | // blank summary, so let's get an automatic one if |
47 | 47 | // applicable (the appending bit prevents autosummaries |
48 | 48 | // from appearing otherwise). |
49 | | - $oldtext = $article->fetchContent(); |
| 49 | + $oldtext = $article->getRawText(); // current revision |
50 | 50 | $summary = $article->getAutosummary( $oldtext, $text, $flags ); |
51 | 51 | } |
52 | 52 | $summary .= wfMsg( 'word-separator' ) . wfMsg( 'checkpoint-notice' ); |
Index: branches/REL1_18/phase3/RELEASE-NOTES-1.18 |
— | — | @@ -202,6 +202,7 @@ |
203 | 203 | * Introduced $wgVaryOnXFPForAPI which will cause the API to send |
204 | 204 | Vary: X-Forwarded-Proto headers. |
205 | 205 | * New maintenance script to refresh image metadata (maintenance/refreshImageMetadata.php) |
| 206 | +* (bug 16428) Include permalink in printable version |
206 | 207 | |
207 | 208 | === Bug fixes in 1.18 === |
208 | 209 | * mw.util.getScript has been implemented (like wfScript in GlobalFunctions.php) |
— | — | @@ -439,6 +440,7 @@ |
440 | 441 | instead require() for included extensions. |
441 | 442 | * Tracking categories are no longer shown in footer for special pages |
442 | 443 | * (bug 30684) Fix bad escaping in mw.message for inexistent messages (i.e. <key>) |
| 444 | +* $wgOverrideSiteFeed no longer double escapes urls. |
443 | 445 | |
444 | 446 | === API changes in 1.18 === |
445 | 447 | * BREAKING CHANGE: action=watch now requires POST and token. |
Property changes on: branches/REL1_18/phase3/RELEASE-NOTES-1.18 |
___________________________________________________________________ |
Modified: svn:mergeinfo |
446 | 448 | Merged /trunk/phase3/RELEASE-NOTES-1.18:r95655,96227,96386,96393,96405,96427,96460,96472 |
447 | 449 | Merged /trunk/phase3/RELEASE-NOTES-1.19:r95655 |
Index: branches/REL1_18/phase3/tests/phpunit/includes/ArticleTest.php |
— | — | @@ -7,7 +7,7 @@ |
8 | 8 | |
9 | 9 | /** creates a title object and its article object */ |
10 | 10 | function setUp() { |
11 | | - $this->title = Title::makeTitle( NS_MAIN, 'somePage' ); |
| 11 | + $this->title = Title::makeTitle( NS_MAIN, 'SomePage' ); |
12 | 12 | $this->article = new Article( $this->title ); |
13 | 13 | |
14 | 14 | } |
Index: branches/REL1_18/phase3/tests/phpunit/includes/IPTest.php |
— | — | @@ -272,10 +272,14 @@ |
273 | 273 | * @covers IP::isPublic |
274 | 274 | */ |
275 | 275 | public function testPrivateIPs() { |
276 | | - $private = array( 'fc::3', 'fc::ff', '::1', '10.0.0.1', '172.16.0.1', '192.168.0.1' ); |
| 276 | + $private = array( 'fc00::3', 'fc00::ff', '::1', '10.0.0.1', '172.16.0.1', '192.168.0.1' ); |
277 | 277 | foreach ( $private as $p ) { |
278 | 278 | $this->assertFalse( IP::isPublic( $p ), "$p is not a public IP address" ); |
279 | 279 | } |
| 280 | + $public = array( '2001:5c0:1000:a::133', 'fc::3' ); |
| 281 | + foreach ( $public as $p ) { |
| 282 | + $this->assertTrue( IP::isPublic( $p ), "$p is a public IP address" ); |
| 283 | + } |
280 | 284 | } |
281 | 285 | |
282 | 286 | // Private wrapper used to test CIDR Parsing. |
Index: branches/REL1_18/phase3/includes/Article.php |
— | — | @@ -1264,101 +1264,6 @@ |
1265 | 1265 | } |
1266 | 1266 | |
1267 | 1267 | /** |
1268 | | - * Auto-generates a deletion reason |
1269 | | - * |
1270 | | - * @param &$hasHistory Boolean: whether the page has a history |
1271 | | - * @return mixed String containing deletion reason or empty string, or boolean false |
1272 | | - * if no revision occurred |
1273 | | - */ |
1274 | | - public function generateReason( &$hasHistory ) { |
1275 | | - global $wgContLang; |
1276 | | - |
1277 | | - $dbw = wfGetDB( DB_MASTER ); |
1278 | | - // Get the last revision |
1279 | | - $rev = Revision::newFromTitle( $this->getTitle() ); |
1280 | | - |
1281 | | - if ( is_null( $rev ) ) { |
1282 | | - return false; |
1283 | | - } |
1284 | | - |
1285 | | - // Get the article's contents |
1286 | | - $contents = $rev->getText(); |
1287 | | - $blank = false; |
1288 | | - |
1289 | | - // If the page is blank, use the text from the previous revision, |
1290 | | - // which can only be blank if there's a move/import/protect dummy revision involved |
1291 | | - if ( $contents == '' ) { |
1292 | | - $prev = $rev->getPrevious(); |
1293 | | - |
1294 | | - if ( $prev ) { |
1295 | | - $contents = $prev->getText(); |
1296 | | - $blank = true; |
1297 | | - } |
1298 | | - } |
1299 | | - |
1300 | | - // Find out if there was only one contributor |
1301 | | - // Only scan the last 20 revisions |
1302 | | - $res = $dbw->select( 'revision', 'rev_user_text', |
1303 | | - array( 'rev_page' => $this->mPage->getID(), $dbw->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0' ), |
1304 | | - __METHOD__, |
1305 | | - array( 'LIMIT' => 20 ) |
1306 | | - ); |
1307 | | - |
1308 | | - if ( $res === false ) { |
1309 | | - // This page has no revisions, which is very weird |
1310 | | - return false; |
1311 | | - } |
1312 | | - |
1313 | | - $hasHistory = ( $res->numRows() > 1 ); |
1314 | | - $row = $dbw->fetchObject( $res ); |
1315 | | - |
1316 | | - if ( $row ) { // $row is false if the only contributor is hidden |
1317 | | - $onlyAuthor = $row->rev_user_text; |
1318 | | - // Try to find a second contributor |
1319 | | - foreach ( $res as $row ) { |
1320 | | - if ( $row->rev_user_text != $onlyAuthor ) { // Bug 22999 |
1321 | | - $onlyAuthor = false; |
1322 | | - break; |
1323 | | - } |
1324 | | - } |
1325 | | - } else { |
1326 | | - $onlyAuthor = false; |
1327 | | - } |
1328 | | - |
1329 | | - // Generate the summary with a '$1' placeholder |
1330 | | - if ( $blank ) { |
1331 | | - // The current revision is blank and the one before is also |
1332 | | - // blank. It's just not our lucky day |
1333 | | - $reason = wfMsgForContent( 'exbeforeblank', '$1' ); |
1334 | | - } else { |
1335 | | - if ( $onlyAuthor ) { |
1336 | | - $reason = wfMsgForContent( 'excontentauthor', '$1', $onlyAuthor ); |
1337 | | - } else { |
1338 | | - $reason = wfMsgForContent( 'excontent', '$1' ); |
1339 | | - } |
1340 | | - } |
1341 | | - |
1342 | | - if ( $reason == '-' ) { |
1343 | | - // Allow these UI messages to be blanked out cleanly |
1344 | | - return ''; |
1345 | | - } |
1346 | | - |
1347 | | - // Replace newlines with spaces to prevent uglyness |
1348 | | - $contents = preg_replace( "/[\n\r]/", ' ', $contents ); |
1349 | | - // Calculate the maximum amount of chars to get |
1350 | | - // Max content length = max comment length - length of the comment (excl. $1) |
1351 | | - $maxLength = 255 - ( strlen( $reason ) - 2 ); |
1352 | | - $contents = $wgContLang->truncate( $contents, $maxLength ); |
1353 | | - // Remove possible unfinished links |
1354 | | - $contents = preg_replace( '/\[\[([^\]]*)\]?$/', '$1', $contents ); |
1355 | | - // Now replace the '$1' placeholder |
1356 | | - $reason = str_replace( '$1', $contents, $reason ); |
1357 | | - |
1358 | | - return $reason; |
1359 | | - } |
1360 | | - |
1361 | | - |
1362 | | - /** |
1363 | 1268 | * UI entry point for page deletion |
1364 | 1269 | */ |
1365 | 1270 | public function delete() { |
— | — | @@ -2035,6 +1940,10 @@ |
2036 | 1941 | return $this->mPage->commitRollback( $fromP, $summary, $bot, $resultDetails, $guser ); |
2037 | 1942 | } |
2038 | 1943 | |
| 1944 | + public function generateReason( &$hasHistory ) { |
| 1945 | + return $this->mPage->getAutoDeleteReason( $hasHistory ); |
| 1946 | + } |
| 1947 | + |
2039 | 1948 | // ****** B/C functions for static methods ( __callStatic is PHP>=5.3 ) ****** // |
2040 | 1949 | public static function selectFields() { |
2041 | 1950 | return WikiPage::selectFields(); |
Index: branches/REL1_18/phase3/includes/parser/Parser.php |
— | — | @@ -667,14 +667,16 @@ |
668 | 668 | * @return Language |
669 | 669 | */ |
670 | 670 | function getFunctionLang() { |
671 | | - global $wgLang; |
672 | | - |
673 | 671 | $target = $this->mOptions->getTargetLanguage(); |
674 | 672 | if ( $target !== null ) { |
675 | 673 | return $target; |
676 | | - } else { |
677 | | - return $this->mOptions->getInterfaceMessage() ? $wgLang : $this->mTitle->getPageLanguage(); |
| 674 | + } elseif( $this->mOptions->getInterfaceMessage() ) { |
| 675 | + global $wgLang; |
| 676 | + return $wgLang; |
| 677 | + } elseif( is_null( $this->mTitle ) ) { |
| 678 | + throw new MWException( __METHOD__.': $this->mTitle is null' ); |
678 | 679 | } |
| 680 | + return $this->mTitle->getPageLanguage(); |
679 | 681 | } |
680 | 682 | |
681 | 683 | /** |
Index: branches/REL1_18/phase3/includes/OutputPage.php |
— | — | @@ -2890,9 +2890,10 @@ |
2891 | 2891 | |
2892 | 2892 | if ( $wgOverrideSiteFeed ) { |
2893 | 2893 | foreach ( $wgOverrideSiteFeed as $type => $feedUrl ) { |
| 2894 | + // Note, this->feedLink escapes the url. |
2894 | 2895 | $tags[] = $this->feedLink( |
2895 | 2896 | $type, |
2896 | | - htmlspecialchars( $feedUrl ), |
| 2897 | + $feedUrl, |
2897 | 2898 | wfMsg( "site-{$type}-feed", $wgSitename ) |
2898 | 2899 | ); |
2899 | 2900 | } |
Property changes on: branches/REL1_18/phase3/includes/OutputPage.php |
___________________________________________________________________ |
Modified: svn:mergeinfo |
2900 | 2901 | Merged /trunk/phase3/includes/OutputPage.php:r95655,96227,96386,96393,96405,96427,96460,96472 |
Index: branches/REL1_18/phase3/includes/SkinTemplate.php |
— | — | @@ -520,7 +520,7 @@ |
521 | 521 | |
522 | 522 | // Append printfooter and debughtml onto bodytext so that skins that were already |
523 | 523 | // using bodytext before they were split out don't suddenly start not outputting information |
524 | | - $tpl->data['bodytext'] .= Html::element( 'div', array( 'class' => 'printfooter' ), "\n{$tpl->data['printfooter']}" ) . "\n"; |
| 524 | + $tpl->data['bodytext'] .= Html::rawElement( 'div', array( 'class' => 'printfooter' ), "\n{$tpl->data['printfooter']}" ) . "\n"; |
525 | 525 | $tpl->data['bodytext'] .= $tpl->data['debughtml']; |
526 | 526 | |
527 | 527 | // allow extensions adding stuff after the page content. |
Index: branches/REL1_18/phase3/includes/WikiPage.php |
— | — | @@ -574,7 +574,7 @@ |
575 | 575 | * @return string MW timestamp of last article revision |
576 | 576 | */ |
577 | 577 | public function getTimestamp() { |
578 | | - // Check if the field has been filled by ParserCache::get() |
| 578 | + // Check if the field has been filled by WikiPage::setTimestamp() |
579 | 579 | if ( !$this->mTimestamp ) { |
580 | 580 | $this->loadLastEdit(); |
581 | 581 | } |
— | — | @@ -1095,7 +1095,7 @@ |
1096 | 1096 | |
1097 | 1097 | # Provide autosummaries if one is not provided and autosummaries are enabled. |
1098 | 1098 | if ( $wgUseAutomaticEditSummaries && $flags & EDIT_AUTOSUMMARY && $summary == '' ) { |
1099 | | - $summary = $this->getAutosummary( $oldtext, $text, $flags ); |
| 1099 | + $summary = self::getAutosummary( $oldtext, $text, $flags ); |
1100 | 1100 | } |
1101 | 1101 | |
1102 | 1102 | $editInfo = $this->prepareTextForEdit( $text, null, $user ); |
— | — | @@ -2408,6 +2408,100 @@ |
2409 | 2409 | } |
2410 | 2410 | |
2411 | 2411 | /** |
| 2412 | + * Auto-generates a deletion reason |
| 2413 | + * |
| 2414 | + * @param &$hasHistory Boolean: whether the page has a history |
| 2415 | + * @return mixed String containing deletion reason or empty string, or boolean false |
| 2416 | + * if no revision occurred |
| 2417 | + */ |
| 2418 | + public function getAutoDeleteReason( &$hasHistory ) { |
| 2419 | + global $wgContLang; |
| 2420 | + |
| 2421 | + $dbw = wfGetDB( DB_MASTER ); |
| 2422 | + // Get the last revision |
| 2423 | + $rev = Revision::newFromTitle( $this->getTitle() ); |
| 2424 | + |
| 2425 | + if ( is_null( $rev ) ) { |
| 2426 | + return false; |
| 2427 | + } |
| 2428 | + |
| 2429 | + // Get the article's contents |
| 2430 | + $contents = $rev->getText(); |
| 2431 | + $blank = false; |
| 2432 | + |
| 2433 | + // If the page is blank, use the text from the previous revision, |
| 2434 | + // which can only be blank if there's a move/import/protect dummy revision involved |
| 2435 | + if ( $contents == '' ) { |
| 2436 | + $prev = $rev->getPrevious(); |
| 2437 | + |
| 2438 | + if ( $prev ) { |
| 2439 | + $contents = $prev->getText(); |
| 2440 | + $blank = true; |
| 2441 | + } |
| 2442 | + } |
| 2443 | + |
| 2444 | + // Find out if there was only one contributor |
| 2445 | + // Only scan the last 20 revisions |
| 2446 | + $res = $dbw->select( 'revision', 'rev_user_text', |
| 2447 | + array( 'rev_page' => $this->getID(), $dbw->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0' ), |
| 2448 | + __METHOD__, |
| 2449 | + array( 'LIMIT' => 20 ) |
| 2450 | + ); |
| 2451 | + |
| 2452 | + if ( $res === false ) { |
| 2453 | + // This page has no revisions, which is very weird |
| 2454 | + return false; |
| 2455 | + } |
| 2456 | + |
| 2457 | + $hasHistory = ( $res->numRows() > 1 ); |
| 2458 | + $row = $dbw->fetchObject( $res ); |
| 2459 | + |
| 2460 | + if ( $row ) { // $row is false if the only contributor is hidden |
| 2461 | + $onlyAuthor = $row->rev_user_text; |
| 2462 | + // Try to find a second contributor |
| 2463 | + foreach ( $res as $row ) { |
| 2464 | + if ( $row->rev_user_text != $onlyAuthor ) { // Bug 22999 |
| 2465 | + $onlyAuthor = false; |
| 2466 | + break; |
| 2467 | + } |
| 2468 | + } |
| 2469 | + } else { |
| 2470 | + $onlyAuthor = false; |
| 2471 | + } |
| 2472 | + |
| 2473 | + // Generate the summary with a '$1' placeholder |
| 2474 | + if ( $blank ) { |
| 2475 | + // The current revision is blank and the one before is also |
| 2476 | + // blank. It's just not our lucky day |
| 2477 | + $reason = wfMsgForContent( 'exbeforeblank', '$1' ); |
| 2478 | + } else { |
| 2479 | + if ( $onlyAuthor ) { |
| 2480 | + $reason = wfMsgForContent( 'excontentauthor', '$1', $onlyAuthor ); |
| 2481 | + } else { |
| 2482 | + $reason = wfMsgForContent( 'excontent', '$1' ); |
| 2483 | + } |
| 2484 | + } |
| 2485 | + |
| 2486 | + if ( $reason == '-' ) { |
| 2487 | + // Allow these UI messages to be blanked out cleanly |
| 2488 | + return ''; |
| 2489 | + } |
| 2490 | + |
| 2491 | + // Replace newlines with spaces to prevent uglyness |
| 2492 | + $contents = preg_replace( "/[\n\r]/", ' ', $contents ); |
| 2493 | + // Calculate the maximum amount of chars to get |
| 2494 | + // Max content length = max comment length - length of the comment (excl. $1) |
| 2495 | + $maxLength = 255 - ( strlen( $reason ) - 2 ); |
| 2496 | + $contents = $wgContLang->truncate( $contents, $maxLength ); |
| 2497 | + // Remove possible unfinished links |
| 2498 | + $contents = preg_replace( '/\[\[([^\]]*)\]?$/', '$1', $contents ); |
| 2499 | + // Now replace the '$1' placeholder |
| 2500 | + $reason = str_replace( '$1', $contents, $reason ); |
| 2501 | + |
| 2502 | + return $reason; |
| 2503 | + } |
| 2504 | + |
| 2505 | + /** |
2412 | 2506 | * Get parser options suitable for rendering the primary article wikitext |
2413 | 2507 | * @param $canonical boolean Determines that the generated options must not depend on user preferences (see bug 14404) |
2414 | 2508 | * @return mixed ParserOptions object or boolean false |
Index: branches/REL1_18/phase3/includes/Skin.php |
— | — | @@ -705,9 +705,20 @@ |
706 | 706 | return $bottomScriptText; |
707 | 707 | } |
708 | 708 | |
709 | | - /** @return string Retrievied from HTML text */ |
| 709 | + /** |
| 710 | + * Text with the permalink to the source page, |
| 711 | + * usually shown on the footer of a printed page |
| 712 | + * |
| 713 | + * @return string HTML text with an URL |
| 714 | + */ |
710 | 715 | function printSource() { |
711 | | - $url = htmlspecialchars( $this->getTitle()->getFullURL() ); |
| 716 | + $oldid = $this->getRevisionId(); |
| 717 | + if ( $oldid ) { |
| 718 | + $url = htmlspecialchars( $this->getTitle()->getCanonicalURL( 'oldid=' . $oldid ) ); |
| 719 | + } else { |
| 720 | + // oldid not available for non existing pages |
| 721 | + $url = htmlspecialchars( $this->getTitle()->getCanonicalURL() ); |
| 722 | + } |
712 | 723 | return wfMsg( 'retrievedfrom', '<a href="' . $url . '">' . $url . '</a>' ); |
713 | 724 | } |
714 | 725 | |
Index: branches/REL1_18/phase3/includes/IP.php |
— | — | @@ -373,7 +373,7 @@ |
374 | 374 | static $privateRanges = false; |
375 | 375 | if ( !$privateRanges ) { |
376 | 376 | $privateRanges = array( |
377 | | - array( 'fc::', 'fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' ), # RFC 4193 (local) |
| 377 | + array( 'fc00::', 'fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' ), # RFC 4193 (local) |
378 | 378 | array( '0:0:0:0:0:0:0:1', '0:0:0:0:0:0:0:1' ), # loopback |
379 | 379 | ); |
380 | 380 | } |