r23053 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r23052‎ | r23053 | r23054 >
Date:02:48, 18 June 2007
Author:aaron
Status:old
Tags:
Comment:
*Update branch
Modified paths:
  • /branches/phase3_rev_deleted/includes/Article.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/AutoLoader.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/BagOStuff.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/Block.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/ChangesList.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/DatabaseOracle.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/DatabasePostgres.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/DefaultSettings.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/DifferenceEngine.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/EditPage.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/ExternalStore.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/GlobalFunctions.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/IP.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/ImageGallery.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/ImagePage.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/Linker.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/LogPage.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/MacBinary.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/Math.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/ObjectCache.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/OutputPage.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/Parser.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/ParserOutput.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/PatrolLog.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/ProtectionForm.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/QueryPage.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/RecentChange.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SearchEngine.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SearchMySQL.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/Setup.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/Skin.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SkinTemplate.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialBlockip.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialBooksources.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialConfirmemail.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialEmailuser.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialIpblocklist.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialLog.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialNewpages.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialPage.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialPreferences.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialProtectedpages.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialRecentchanges.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialRevisiondelete.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialSearch.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialSpecialpages.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialUndelete.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialUpload.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialUserlogin.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialVersion.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialWantedpages.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/SpecialWhatlinkshere.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/Title.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/User.php (modified) (history)
  • /branches/phase3_rev_deleted/includes/Xml.php (modified) (history)
  • /branches/phase3_rev_deleted/languages/messages/MessagesEn.php (modified) (history)

Diff [purge]

Index: branches/phase3_rev_deleted/languages/messages/MessagesEn.php
@@ -114,14 +114,13 @@
115115 * Skin names. If any key is not specified, the English one will be used.
116116 */
117117 $skinNames = array(
118 - 'standard' => 'Classic',
119 - 'nostalgia' => 'Nostalgia',
 118+ 'standard' => 'Classic',
 119+ 'nostalgia' => 'Nostalgia',
120120 'cologneblue' => 'Cologne Blue',
121 - 'davinci' => 'DaVinci',
122 - 'mono' => 'Mono',
123 - 'monobook' => 'MonoBook',
124 - 'myskin' => 'MySkin',
125 - 'chick' => 'Chick'
 121+ 'monobook' => 'MonoBook',
 122+ 'myskin' => 'MySkin',
 123+ 'chick' => 'Chick',
 124+ 'simple' => 'Simple'
126125 );
127126
128127 /**
@@ -281,6 +280,7 @@
282281 'img_width' => array( 1, '$1px' ),
283282 'img_center' => array( 1, 'center', 'centre' ),
284283 'img_framed' => array( 1, 'framed', 'enframed', 'frame' ),
 284+ 'img_frameless' => array( 1, 'frameless' ),
285285 'img_page' => array( 1, 'page=$1', 'page $1' ),
286286 'img_upright' => array( 1, 'upright', 'upright=$1', 'upright $1' ),
287287 'img_border' => array( 1, 'border' ),
@@ -338,7 +338,7 @@
339339 'padleft' => array( 0, 'PADLEFT' ),
340340 'padright' => array( 0, 'PADRIGHT' ),
341341 'special' => array( 0, 'special', ),
342 - 'defaultsort' => array( 1, 'DEFAULTSORT:' ),
 342+ 'defaultsort' => array( 1, 'DEFAULTSORT:', 'DEFAULTSORTKEY:', 'DEFAULTCATEGORYSORT:' ),
343343 );
344344
345345 /**
@@ -368,12 +368,14 @@
369369 'Uncategorizedpages' => array( 'Uncategorizedpages' ),
370370 'Uncategorizedcategories' => array( 'Uncategorizedcategories' ),
371371 'Uncategorizedimages' => array( 'Uncategorizedimages' ),
 372+ 'Uncategorizedtemplates' => array( 'Uncategorizedtemplates' ),
372373 'Unusedcategories' => array( 'Unusedcategories' ),
373374 'Unusedimages' => array( 'Unusedimages' ),
374 - 'Wantedpages' => array( 'Wantedpages' ),
 375+ 'Wantedpages' => array( 'Wantedpages', 'Brokenlinks' ),
375376 'Wantedcategories' => array( 'Wantedcategories' ),
376377 'Mostlinked' => array( 'Mostlinked' ),
377378 'Mostlinkedcategories' => array( 'Mostlinkedcategories' ),
 379+ 'Mostlinkedtemplates' => array( 'Mostlinkedtemplates' ),
378380 'Mostcategories' => array( 'Mostcategories' ),
379381 'Mostimages' => array( 'Mostimages' ),
380382 'Mostrevisions' => array( 'Mostrevisions' ),
@@ -456,119 +458,117 @@
457459 ** recentchanges-url|recentchanges
458460 ** randompage-url|randompage
459461 ** helppage|help
460 -** sitesupport-url|sitesupport',
 462+** sitesupport-url|sitesupport', # don't translate or duplicate this message to other languages
461463
462464 # User preference toggles
463 -'tog-underline' => 'Underline links:',
464 -'tog-highlightbroken' => 'Format broken links <a href="" class="new">like this</a> (alternative: like this<a href="" class="internal">?</a>).',
465 -'tog-justify' => 'Justify paragraphs',
466 -'tog-hideminor' => 'Hide minor edits in recent changes',
467 -'tog-extendwatchlist' => 'Expand watchlist to show all applicable changes',
468 -'tog-usenewrc' => 'Enhanced recent changes (JavaScript)',
469 -'tog-numberheadings' => 'Auto-number headings',
470 -'tog-showtoolbar' => 'Show edit toolbar (JavaScript)',
471 -'tog-editondblclick' => 'Edit pages on double click (JavaScript)',
472 -'tog-editsection' => 'Enable section editing via [edit] links',
473 -'tog-editsectiononrightclick' => 'Enable section editing by right clicking<br /> on section titles (JavaScript)',
474 -'tog-showtoc' => 'Show table of contents (for pages with more than 3 headings)',
475 -'tog-rememberpassword' => 'Remember my login on this computer',
476 -'tog-editwidth' => 'Edit box has full width',
477 -'tog-watchcreations' => 'Add pages I create to my watchlist',
478 -'tog-watchdefault' => 'Add pages I edit to my watchlist',
479 -'tog-watchmoves' => 'Add pages I move to my watchlist',
480 -'tog-watchdeletion' => 'Add pages I delete to my watchlist',
481 -'tog-minordefault' => 'Mark all edits minor by default',
482 -'tog-previewontop' => 'Show preview before edit box',
483 -'tog-previewonfirst' => 'Show preview on first edit',
484 -'tog-nocache' => 'Disable page caching',
485 -'tog-enotifwatchlistpages' => 'E-mail me when a page I\'m watching is changed',
486 -'tog-enotifusertalkpages' => 'E-mail me when my user talk page is changed',
487 -'tog-enotifminoredits' => 'E-mail me also for minor edits of pages',
488 -'tog-enotifrevealaddr' => 'Reveal my e-mail address in notification mails',
489 -'tog-shownumberswatching' => 'Show the number of watching users',
490 -'tog-fancysig' => 'Raw signatures (without automatic link)',
491 -'tog-externaleditor' => 'Use external editor by default',
492 -'tog-externaldiff' => 'Use external diff by default',
493 -'tog-showjumplinks' => 'Enable "jump to" accessibility links',
494 -'tog-uselivepreview' => 'Use live preview (JavaScript) (Experimental)',
495 -'tog-forceeditsummary' => 'Prompt me when entering a blank edit summary',
496 -'tog-watchlisthideown' => 'Hide my edits from the watchlist',
497 -'tog-watchlisthidebots' => 'Hide bot edits from the watchlist',
498 -'tog-watchlisthideminor' => 'Hide minor edits from the watchlist',
499 -'tog-nolangconversion' => 'Disable variants conversion',
500 -'tog-ccmeonemails' => 'Send me copies of emails I send to other users',
501 -'tog-diffonly' => "Don't show page content below diffs",
 465+'tog-underline' => 'Underline links:',
 466+'tog-highlightbroken' => 'Format broken links <a href="" class="new">like this</a> (alternative: like this<a href="" class="internal">?</a>).',
 467+'tog-justify' => 'Justify paragraphs',
 468+'tog-hideminor' => 'Hide minor edits in recent changes',
 469+'tog-extendwatchlist' => 'Expand watchlist to show all applicable changes',
 470+'tog-usenewrc' => 'Enhanced recent changes (JavaScript)',
 471+'tog-numberheadings' => 'Auto-number headings',
 472+'tog-showtoolbar' => 'Show edit toolbar (JavaScript)',
 473+'tog-editondblclick' => 'Edit pages on double click (JavaScript)',
 474+'tog-editsection' => 'Enable section editing via [edit] links',
 475+'tog-editsectiononrightclick' => 'Enable section editing by right clicking<br /> on section titles (JavaScript)',
 476+'tog-showtoc' => 'Show table of contents (for pages with more than 3 headings)',
 477+'tog-rememberpassword' => 'Remember my login on this computer',
 478+'tog-editwidth' => 'Edit box has full width',
 479+'tog-watchcreations' => 'Add pages I create to my watchlist',
 480+'tog-watchdefault' => 'Add pages I edit to my watchlist',
 481+'tog-watchmoves' => 'Add pages I move to my watchlist',
 482+'tog-watchdeletion' => 'Add pages I delete to my watchlist',
 483+'tog-minordefault' => 'Mark all edits minor by default',
 484+'tog-previewontop' => 'Show preview before edit box',
 485+'tog-previewonfirst' => 'Show preview on first edit',
 486+'tog-nocache' => 'Disable page caching',
 487+'tog-enotifwatchlistpages' => "E-mail me when a page I'm watching is changed",
 488+'tog-enotifusertalkpages' => 'E-mail me when my user talk page is changed',
 489+'tog-enotifminoredits' => 'E-mail me also for minor edits of pages',
 490+'tog-enotifrevealaddr' => 'Reveal my e-mail address in notification mails',
 491+'tog-shownumberswatching' => 'Show the number of watching users',
 492+'tog-fancysig' => 'Raw signatures (without automatic link)',
 493+'tog-externaleditor' => 'Use external editor by default',
 494+'tog-externaldiff' => 'Use external diff by default',
 495+'tog-showjumplinks' => 'Enable "jump to" accessibility links',
 496+'tog-uselivepreview' => 'Use live preview (JavaScript) (Experimental)',
 497+'tog-forceeditsummary' => 'Prompt me when entering a blank edit summary',
 498+'tog-watchlisthideown' => 'Hide my edits from the watchlist',
 499+'tog-watchlisthidebots' => 'Hide bot edits from the watchlist',
 500+'tog-watchlisthideminor' => 'Hide minor edits from the watchlist',
 501+'tog-nolangconversion' => 'Disable variants conversion',
 502+'tog-ccmeonemails' => 'Send me copies of emails I send to other users',
 503+'tog-diffonly' => "Don't show page content below diffs",
502504
503 -'underline-always' => 'Always',
504 -'underline-never' => 'Never',
 505+'underline-always' => 'Always',
 506+'underline-never' => 'Never',
505507 'underline-default' => 'Browser default',
506508
507509 'skinpreview' => '(Preview)',
508510
509 -# dates
510 -'sunday' => 'Sunday',
511 -'monday' => 'Monday',
512 -'tuesday' => 'Tuesday',
513 -'wednesday' => 'Wednesday',
514 -'thursday' => 'Thursday',
515 -'friday' => 'Friday',
516 -'saturday' => 'Saturday',
517 -'sun' => 'Sun',
518 -'mon' => 'Mon',
519 -'tue' => 'Tue',
520 -'wed' => 'Wed',
521 -'thu' => 'Thu',
522 -'fri' => 'Fri',
523 -'sat' => 'Sat',
524 -'january' => 'January',
525 -'february' => 'February',
526 -'march' => 'March',
527 -'april' => 'April',
528 -'may_long' => 'May',
529 -'june' => 'June',
530 -'july' => 'July',
531 -'august' => 'August',
532 -'september' => 'September',
533 -'october' => 'October',
534 -'november' => 'November',
535 -'december' => 'December',
536 -'january-gen' => 'January',
537 -'february-gen' => 'February',
538 -'march-gen' => 'March',
539 -'april-gen' => 'April',
540 -'may-gen' => 'May',
541 -'june-gen' => 'June',
542 -'july-gen' => 'July',
543 -'august-gen' => 'August',
 511+# Dates
 512+'sunday' => 'Sunday',
 513+'monday' => 'Monday',
 514+'tuesday' => 'Tuesday',
 515+'wednesday' => 'Wednesday',
 516+'thursday' => 'Thursday',
 517+'friday' => 'Friday',
 518+'saturday' => 'Saturday',
 519+'sun' => 'Sun',
 520+'mon' => 'Mon',
 521+'tue' => 'Tue',
 522+'wed' => 'Wed',
 523+'thu' => 'Thu',
 524+'fri' => 'Fri',
 525+'sat' => 'Sat',
 526+'january' => 'January',
 527+'february' => 'February',
 528+'march' => 'March',
 529+'april' => 'April',
 530+'may_long' => 'May',
 531+'june' => 'June',
 532+'july' => 'July',
 533+'august' => 'August',
 534+'september' => 'September',
 535+'october' => 'October',
 536+'november' => 'November',
 537+'december' => 'December',
 538+'january-gen' => 'January',
 539+'february-gen' => 'February',
 540+'march-gen' => 'March',
 541+'april-gen' => 'April',
 542+'may-gen' => 'May',
 543+'june-gen' => 'June',
 544+'july-gen' => 'July',
 545+'august-gen' => 'August',
544546 'september-gen' => 'September',
545 -'october-gen' => 'October',
546 -'november-gen' => 'November',
547 -'december-gen' => 'December',
548 -'jan' => 'Jan',
549 -'feb' => 'Feb',
550 -'mar' => 'Mar',
551 -'apr' => 'Apr',
552 -'may' => 'May',
553 -'jun' => 'Jun',
554 -'jul' => 'Jul',
555 -'aug' => 'Aug',
556 -'sep' => 'Sep',
557 -'oct' => 'Oct',
558 -'nov' => 'Nov',
559 -'dec' => 'Dec',
560 -# Bits of text used by many pages:
561 -#
562 -'categories' => 'Categories',
563 -'pagecategories' => '{{PLURAL:$1|Category|Categories}}',
564 -'pagecategorieslink' => 'Special:Categories',
565 -'category_header' => 'Articles in category "$1"',
566 -'subcategories' => 'Subcategories',
 547+'october-gen' => 'October',
 548+'november-gen' => 'November',
 549+'december-gen' => 'December',
 550+'jan' => 'Jan',
 551+'feb' => 'Feb',
 552+'mar' => 'Mar',
 553+'apr' => 'Apr',
 554+'may' => 'May',
 555+'jun' => 'Jun',
 556+'jul' => 'Jul',
 557+'aug' => 'Aug',
 558+'sep' => 'Sep',
 559+'oct' => 'Oct',
 560+'nov' => 'Nov',
 561+'dec' => 'Dec',
 562+
 563+# Bits of text used by many pages
 564+'categories' => 'Categories',
 565+'pagecategories' => '{{PLURAL:$1|Category|Categories}}',
 566+'pagecategorieslink' => 'Special:Categories', # don't translate or duplicate this message to other languages
 567+'category_header' => 'Articles in category "$1"',
 568+'subcategories' => 'Subcategories',
567569 'category-media-header' => 'Media in category "$1"',
568570
569 -
570 -'linkprefix' => '/^(.*?)([a-zA-Z\x80-\xff]+)$/sD',
571 -'mainpage' => 'Main Page',
572 -'mainpagetext' => "<big>'''MediaWiki has been successfully installed.'''</big>",
 571+'linkprefix' => '/^(.*?)([a-zA-Z\x80-\xff]+)$/sD', # only translate this message to other languages if you have to change it
 572+'mainpagetext' => "<big>'''MediaWiki has been successfully installed.'''</big>",
573573 'mainpagedocfooter' => "Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
574574
575575 == Getting started ==
@@ -577,280 +577,277 @@
578578 * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
579579 * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]",
580580
581 -'portal' => 'Community portal',
582 -'portal-url' => 'Project:Community Portal',
583 -'about' => 'About',
584 -'aboutsite' => 'About {{SITENAME}}',
585 -'aboutpage' => 'Project:About',
586 -'article' => 'Content page',
587 -'help' => 'Help',
588 -'helppage' => 'Help:Contents',
589 -'bugreports' => 'Bug reports',
590 -'bugreportspage' => 'Project:Bug reports',
591 -'sitesupport' => 'Donations',
592 -'sitesupport-url' => 'Project:Site support',
593 -'faq' => 'FAQ',
594 -'faqpage' => 'Project:FAQ',
595 -'edithelp' => 'Editing help',
596 -'newwindow' => '(opens in new window)',
597 -'edithelppage' => 'Help:Editing',
598 -'cancel' => 'Cancel',
599 -'qbfind' => 'Find',
600 -'qbbrowse' => 'Browse',
601 -'qbedit' => 'Edit',
602 -'qbpageoptions' => 'This page',
603 -'qbpageinfo' => 'Context',
604 -'qbmyoptions' => 'My pages',
605 -'qbspecialpages' => 'Special pages',
606 -'moredotdotdot' => 'More...',
607 -'mypage' => 'My page',
608 -'mytalk' => 'My talk',
609 -'anontalk' => 'Talk for this IP',
610 -'navigation' => 'Navigation',
 581+'about' => 'About',
 582+'article' => 'Content page',
 583+'newwindow' => '(opens in new window)',
 584+'cancel' => 'Cancel',
 585+'qbfind' => 'Find',
 586+'qbbrowse' => 'Browse',
 587+'qbedit' => 'Edit',
 588+'qbpageoptions' => 'This page',
 589+'qbpageinfo' => 'Context',
 590+'qbmyoptions' => 'My pages',
 591+'qbspecialpages' => 'Special pages',
 592+'moredotdotdot' => 'More...',
 593+'mypage' => 'My page',
 594+'mytalk' => 'My talk',
 595+'anontalk' => 'Talk for this IP',
 596+'navigation' => 'Navigation',
611597
612598 # Metadata in edit box
613599 'metadata_help' => 'Metadata:',
614600
615 -'currentevents' => 'Current events',
616 -'currentevents-url' => 'Current events',
617 -
618 -'disclaimers' => 'Disclaimers',
619 -'disclaimerpage' => 'Project:General disclaimer',
620 -'privacy' => 'Privacy policy',
621 -'privacypage' => 'Project:Privacy policy',
622 -'errorpagetitle' => 'Error',
623 -'returnto' => 'Return to $1.',
624 -'tagline' => 'From {{SITENAME}}',
625 -'search' => 'Search',
626 -'searchbutton' => 'Search',
627 -'go' => 'Go',
628 -'searcharticle' => 'Go',
629 -'history' => 'Page history',
630 -'history_short' => 'History',
631 -'updatedmarker' => 'updated since my last visit',
632 -'info_short' => 'Information',
633 -'printableversion' => 'Printable version',
634 -'permalink' => 'Permanent link',
635 -'print' => 'Print',
636 -'edit' => 'Edit',
637 -'editthispage' => 'Edit this page',
638 -'delete' => 'Delete',
639 -'deletethispage' => 'Delete this page',
640 -'undelete_short' => 'Undelete {{PLURAL:$1|one edit|$1 edits}}',
641 -'protect' => 'Protect',
642 -'protect_change' => 'change protection',
643 -'protectthispage' => 'Protect this page',
644 -'unprotect' => 'unprotect',
 601+'errorpagetitle' => 'Error',
 602+'returnto' => 'Return to $1.',
 603+'tagline' => 'From {{SITENAME}}',
 604+'help' => 'Help',
 605+'search' => 'Search',
 606+'searchbutton' => 'Search',
 607+'go' => 'Go',
 608+'searcharticle' => 'Go',
 609+'history' => 'Page history',
 610+'history_short' => 'History',
 611+'updatedmarker' => 'updated since my last visit',
 612+'info_short' => 'Information',
 613+'printableversion' => 'Printable version',
 614+'permalink' => 'Permanent link',
 615+'print' => 'Print',
 616+'edit' => 'Edit',
 617+'editthispage' => 'Edit this page',
 618+'delete' => 'Delete',
 619+'deletethispage' => 'Delete this page',
 620+'undelete_short' => 'Undelete {{PLURAL:$1|one edit|$1 edits}}',
 621+'protect' => 'Protect',
 622+'protect_change' => 'change protection',
 623+'protectthispage' => 'Protect this page',
 624+'unprotect' => 'unprotect',
645625 'unprotectthispage' => 'Unprotect this page',
646 -'newpage' => 'New page',
647 -'talkpage' => 'Discuss this page',
648 -'talkpagelinktext' => 'Talk',
649 -'specialpage' => 'Special Page',
650 -'personaltools' => 'Personal tools',
651 -'postcomment' => 'Post a comment',
652 -'addsection' => '+',
653 -'articlepage' => 'View content page',
654 -'talk' => 'Discussion',
655 -'views' => 'Views',
656 -'toolbox' => 'Toolbox',
657 -'userpage' => 'View user page',
658 -'projectpage' => 'View project page',
659 -'imagepage' => 'View image page',
660 -'mediawikipage' => 'View message page',
661 -'templatepage' => 'View template page',
662 -'viewhelppage' => 'View help page',
663 -'categorypage' => 'View category page',
664 -'viewtalkpage' => 'View discussion',
665 -'otherlanguages' => 'In other languages',
666 -'redirectedfrom' => '(Redirected from $1)',
667 -'redirectpagesub' => 'Redirect page',
668 -'lastmodifiedat' => 'This page was last modified $2, $1.', //$1 date, $2 time
669 -'viewcount' => 'This page has been accessed {{PLURAL:$1|one time|$1 times}}.',
670 -'copyright' => 'Content is available under $1.',
671 -'protectedpage' => 'Protected page',
672 -'jumpto' => 'Jump to:',
673 -'jumptonavigation' => 'navigation',
674 -'jumptosearch' => 'search',
 626+'newpage' => 'New page',
 627+'talkpage' => 'Discuss this page',
 628+'talkpagelinktext' => 'Talk',
 629+'specialpage' => 'Special Page',
 630+'personaltools' => 'Personal tools',
 631+'postcomment' => 'Post a comment',
 632+'addsection' => '+', # don't translate or duplicate this message to other languages
 633+'articlepage' => 'View content page',
 634+'talk' => 'Discussion',
 635+'views' => 'Views',
 636+'toolbox' => 'Toolbox',
 637+'userpage' => 'View user page',
 638+'projectpage' => 'View project page',
 639+'imagepage' => 'View image page',
 640+'mediawikipage' => 'View message page',
 641+'templatepage' => 'View template page',
 642+'viewhelppage' => 'View help page',
 643+'categorypage' => 'View category page',
 644+'viewtalkpage' => 'View discussion',
 645+'otherlanguages' => 'In other languages',
 646+'redirectedfrom' => '(Redirected from $1)',
 647+'redirectpagesub' => 'Redirect page',
 648+'lastmodifiedat' => 'This page was last modified $2, $1.', # $1 date, $2 time
 649+'viewcount' => 'This page has been accessed {{PLURAL:$1|one time|$1 times}}.',
 650+'protectedpage' => 'Protected page',
 651+'jumpto' => 'Jump to:',
 652+'jumptonavigation' => 'navigation',
 653+'jumptosearch' => 'search',
675654
 655+# All link text and link target definitions of links into project namespace that get used by other message strings, with the exception of user group pages (see grouppage) and the disambiguation template definition (see disambiguations).
 656+'aboutsite' => 'About {{SITENAME}}',
 657+'aboutpage' => 'Project:About',
 658+'bugreports' => 'Bug reports',
 659+'bugreportspage' => 'Project:Bug reports',
 660+'copyright' => 'Content is available under $1.',
 661+'copyrightpagename' => '{{SITENAME}} copyright',
 662+'copyrightpage' => 'Project:Copyrights',
 663+'currentevents' => 'Current events',
 664+'currentevents-url' => 'Current events',
 665+'disclaimers' => 'Disclaimers',
 666+'disclaimerpage' => 'Project:General disclaimer',
 667+'edithelp' => 'Editing help',
 668+'edithelppage' => 'Help:Editing',
 669+'faq' => 'FAQ',
 670+'faqpage' => 'Project:FAQ',
 671+'helppage' => 'Help:Contents',
 672+'mainpage' => 'Main Page',
 673+'policy-url' => 'Project:Policy',
 674+'portal' => 'Community portal',
 675+'portal-url' => 'Project:Community Portal',
 676+'privacy' => 'Privacy policy',
 677+'privacypage' => 'Project:Privacy policy',
 678+'sitesupport' => 'Donations',
 679+'sitesupport-url' => 'Project:Site support',
 680+
676681 'badaccess' => 'Permission error',
677682 'badaccess-group0' => 'You are not allowed to execute the action you have requested.',
678683 'badaccess-group1' => 'The action you have requested is limited to users in the group $1.',
679684 'badaccess-group2' => 'The action you have requested is limited to users in one of the groups $1.',
680685 'badaccess-groups' => 'The action you have requested is limited to users in one of the groups $1.',
681686
682 -'versionrequired' => 'Version $1 of MediaWiki required',
 687+'versionrequired' => 'Version $1 of MediaWiki required',
683688 'versionrequiredtext' => 'Version $1 of MediaWiki is required to use this page. See [[Special:Version|version page]].',
684689
685 -'ok' => 'OK',
686 -'sitetitle' => '{{SITENAME}}',
687 -'pagetitle' => '$1 - {{SITENAME}}',
688 -'sitesubtitle' => '',
689 -'retrievedfrom' => 'Retrieved from "$1"',
690 -'youhavenewmessages' => 'You have $1 ($2).',
691 -'newmessageslink' => 'new messages',
 690+'ok' => 'OK',
 691+'sitetitle' => '{{SITENAME}}', # don't translate or duplicate this message to other languages
 692+'pagetitle' => '$1 - {{SITENAME}}',
 693+'sitesubtitle' => '', # don't translate or duplicate this message to other languages
 694+'retrievedfrom' => 'Retrieved from "$1"',
 695+'youhavenewmessages' => 'You have $1 ($2).',
 696+'newmessageslink' => 'new messages',
692697 'newmessagesdifflink' => 'last change',
693 -'editsection'=>'edit',
694 -'editold'=>'edit',
695 -'editsectionhint' => 'Edit section: $1',
696 -'toc' => 'Contents',
697 -'showtoc' => 'show',
698 -'hidetoc' => 'hide',
699 -'thisisdeleted' => 'View or restore $1?',
700 -'viewdeleted' => 'View $1?',
701 -'restorelink' => '{{PLURAL:$1|one deleted edit|$1 deleted edits}}',
702 -'feedlinks' => 'Feed:',
703 -'feed-invalid' => 'Invalid subscription feed type.',
704 -'feed-atom' => 'Atom',
705 -'feed-rss' => 'RSS',
706 -'sitenotice' => '-', # the equivalent to wgSiteNotice
707 -'anonnotice' => '-',
 698+'editsection' => 'edit',
 699+'editold' => 'edit',
 700+'editsectionhint' => 'Edit section: $1',
 701+'toc' => 'Contents',
 702+'showtoc' => 'show',
 703+'hidetoc' => 'hide',
 704+'thisisdeleted' => 'View or restore $1?',
 705+'viewdeleted' => 'View $1?',
 706+'restorelink' => '{{PLURAL:$1|one deleted edit|$1 deleted edits}}',
 707+'feedlinks' => 'Feed:',
 708+'feed-invalid' => 'Invalid subscription feed type.',
 709+'feed-atom' => 'Atom', # only translate this message to other languages if you have to change it
 710+'feed-rss' => 'RSS', # only translate this message to other languages if you have to change it
 711+'sitenotice' => '-', # the equivalent to wgSiteNotice; don't translate or duplicate this message to other languages
 712+'anonnotice' => '-', # don't translate or duplicate this message to other languages
708713
709714 # Short words for each namespace, by default used in the 'article' tab in monobook
710 -'nstab-main' => 'Article',
711 -'nstab-user' => 'User page',
712 -'nstab-media' => 'Media page',
713 -'nstab-special' => 'Special',
714 -'nstab-project' => 'Project page',
715 -'nstab-image' => 'File',
 715+'nstab-main' => 'Article',
 716+'nstab-user' => 'User page',
 717+'nstab-media' => 'Media page',
 718+'nstab-special' => 'Special',
 719+'nstab-project' => 'Project page',
 720+'nstab-image' => 'File',
716721 'nstab-mediawiki' => 'Message',
717 -'nstab-template' => 'Template',
718 -'nstab-help' => 'Help page',
719 -'nstab-category' => 'Category',
 722+'nstab-template' => 'Template',
 723+'nstab-help' => 'Help page',
 724+'nstab-category' => 'Category',
720725
721726 # Main script and global functions
722 -#
723 -'nosuchaction' => 'No such action',
724 -'nosuchactiontext' => 'The action specified by the URL is not
 727+'nosuchaction' => 'No such action',
 728+'nosuchactiontext' => 'The action specified by the URL is not
725729 recognized by the wiki',
726730 'nosuchspecialpage' => 'No such special page',
727731 'nospecialpagetext' => 'You have requested an invalid special page, a list of valid special pages may be found at [[Special:Specialpages|special pages list]].',
728732
729733 # General errors
730 -#
731 -'error' => 'Error',
732 -'databaseerror' => 'Database error',
733 -'dberrortext' => 'A database query syntax error has occurred.
 734+'error' => 'Error',
 735+'databaseerror' => 'Database error',
 736+'dberrortext' => 'A database query syntax error has occurred.
734737 This may indicate a bug in the software.
735738 The last attempted database query was:
736739 <blockquote><tt>$1</tt></blockquote>
737740 from within function "<tt>$2</tt>".
738741 MySQL returned error "<tt>$3: $4</tt>".',
739 -'dberrortextcl' => 'A database query syntax error has occurred.
 742+'dberrortextcl' => 'A database query syntax error has occurred.
740743 The last attempted database query was:
741744 "$1"
742745 from within function "$2".
743746 MySQL returned error "$3: $4"',
744 -'noconnect' => 'Sorry! The wiki is experiencing some technical difficulties, and cannot contact the database server. <br />
 747+'noconnect' => 'Sorry! The wiki is experiencing some technical difficulties, and cannot contact the database server. <br />
745748 $1',
746 -'nodb' => 'Could not select database $1',
747 -'cachederror' => 'The following is a cached copy of the requested page, and may not be up to date.',
748 -'laggedslavemode' => 'Warning: Page may not contain recent updates.',
749 -'readonly' => 'Database locked',
750 -'enterlockreason' => 'Enter a reason for the lock, including an estimate
 749+'nodb' => 'Could not select database $1',
 750+'cachederror' => 'The following is a cached copy of the requested page, and may not be up to date.',
 751+'laggedslavemode' => 'Warning: Page may not contain recent updates.',
 752+'readonly' => 'Database locked',
 753+'enterlockreason' => 'Enter a reason for the lock, including an estimate
751754 of when the lock will be released',
752 -'readonlytext' => 'The database is currently locked to new entries and other modifications, probably for routine database maintenance, after which it will be back to normal.
 755+'readonlytext' => 'The database is currently locked to new entries and other modifications, probably for routine database maintenance, after which it will be back to normal.
753756
754757 The administrator who locked it offered this explanation: $1',
755 -'missingarticle' => 'The database did not find the text of a page that it should have found, named "$1".
 758+'missingarticle' => 'The database did not find the text of a page that it should have found, named "$1".
756759
757760 This is usually caused by following an outdated diff or history link to a
758761 page that has been deleted.
759762
760763 If this is not the case, you may have found a bug in the software.
761764 Please report this to an administrator, making note of the URL.',
762 -'readonly_lag' => 'The database has been automatically locked while the slave database servers catch up to the master',
763 -'internalerror' => 'Internal error',
764 -'filecopyerror' => 'Could not copy file "$1" to "$2".',
765 -'filerenameerror' => 'Could not rename file "$1" to "$2".',
766 -'filedeleteerror' => 'Could not delete file "$1".',
767 -'filenotfound' => 'Could not find file "$1".',
768 -'unexpected' => 'Unexpected value: "$1"="$2".',
769 -'formerror' => 'Error: could not submit form',
770 -'badarticleerror' => 'This action cannot be performed on this page.',
771 -'cannotdelete' => 'Could not delete the page or file specified. It may have already been deleted by someone else.<br/>
772 -Pages will not be deleted if it will result in an alternating archive history between these and any archived
773 -revisions for this page. If such is the case, please move this page to another location and delete it there.',
774 -'badtitle' => 'Bad title',
775 -'badtitletext' => 'The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title. It may contain one or more characters which cannot be used in titles.',
776 -'perfdisabled' => 'Sorry! This feature has been temporarily disabled because it slows the database down to the point that no one can use the wiki.',
777 -'perfdisabledsub' => 'Here is a saved copy from $1:', # obsolete?
778 -'perfcached' => 'The following data is cached and may not be up to date.',
779 -'perfcachedts' => 'The following data is cached, and was last updated $1.',
 765+'readonly_lag' => 'The database has been automatically locked while the slave database servers catch up to the master',
 766+'internalerror' => 'Internal error',
 767+'filecopyerror' => 'Could not copy file "$1" to "$2".',
 768+'filerenameerror' => 'Could not rename file "$1" to "$2".',
 769+'filedeleteerror' => 'Could not delete file "$1".',
 770+'filenotfound' => 'Could not find file "$1".',
 771+'unexpected' => 'Unexpected value: "$1"="$2".',
 772+'formerror' => 'Error: could not submit form',
 773+'badarticleerror' => 'This action cannot be performed on this page.',
 774+'cannotdelete' => 'Could not delete the page or file specified. (It may have already been deleted by someone else.)',
 775+'badtitle' => 'Bad title',
 776+'badtitletext' => 'The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title. It may contain one or more characters which cannot be used in titles.',
 777+'perfdisabled' => 'Sorry! This feature has been temporarily disabled because it slows the database down to the point that no one can use the wiki.',
 778+'perfcached' => 'The following data is cached and may not be up to date.',
 779+'perfcachedts' => 'The following data is cached, and was last updated $1.',
780780 'querypage-no-updates' => 'Updates for this page are currently disabled. Data here will not presently be refreshed.',
781781 'wrong_wfQuery_params' => 'Incorrect parameters to wfQuery()<br />
782782 Function: $1<br />
783783 Query: $2',
784 -'viewsource' => 'View source',
785 -'viewsourcefor' => 'for $1',
786 -'protectedpagetext' => 'This page has been locked to prevent editing.',
787 -'viewsourcetext' => 'You can view and copy the source of this page:',
788 -'protectedinterface' => 'This page provides interface text for the software, and is locked to prevent abuse.',
789 -'editinginterface' => "'''Warning:''' You are editing a page which is used to provide interface text for the software. Changes to this page will affect the appearance of the user interface for other users.",
790 -'sqlhidden' => '(SQL query hidden)',
791 -'cascadeprotected' => 'This page has been protected from editing, because it is included in the following {{PLURAL:$1|page|pages}}, which are protected with the "cascading" option turned on:',
 784+'viewsource' => 'View source',
 785+'viewsourcefor' => 'for $1',
 786+'protectedpagetext' => 'This page has been locked to prevent editing.',
 787+'viewsourcetext' => 'You can view and copy the source of this page:',
 788+'protectedinterface' => 'This page provides interface text for the software, and is locked to prevent abuse.',
 789+'editinginterface' => "'''Warning:''' You are editing a page which is used to provide interface text for the software. Changes to this page will affect the appearance of the user interface for other users.",
 790+'sqlhidden' => '(SQL query hidden)',
 791+'cascadeprotected' => 'This page has been protected from editing, because it is included in the following {{PLURAL:$1|page|pages}}, which are protected with the "cascading" option turned on:',
792792
793793 # Login and logout pages
794 -#
795 -'logouttitle' => 'User logout',
796 -'logouttext' => '<strong>You are now logged out.</strong><br />
 794+'logouttitle' => 'User logout',
 795+'logouttext' => '<strong>You are now logged out.</strong><br />
797796 You can continue to use {{SITENAME}} anonymously, or you can log in
798797 again as the same or as a different user. Note that some pages may
799798 continue to be displayed as if you were still logged in, until you clear
800799 your browser cache.',
 800+'welcomecreation' => "== Welcome, $1! ==
801801
802 -'welcomecreation' => "== Welcome, $1! ==
803 -
804802 Your account has been created. Don't forget to change your {{SITENAME}} preferences.",
805 -
806 -'loginpagetitle' => 'User login',
807 -'yourname' => 'Username:',
808 -'yourpassword' => 'Password:',
809 -'yourpasswordagain' => 'Retype password:',
810 -'remembermypassword' => 'Remember my login on this computer',
811 -'yourdomainname' => 'Your domain:',
812 -'externaldberror' => 'There was either an external authentication database error or you are not allowed to update your external account.',
813 -'loginproblem' => '<b>There has been a problem with your login.</b><br />Try again!',
814 -'alreadyloggedin' => "<strong>User $1, you are already logged in!</strong><br />",
815 -
816 -'login' => 'Log in',
817 -'loginprompt' => 'You must have cookies enabled to log in to {{SITENAME}}.',
818 -'userlogin' => 'Log in / create account',
819 -'logout' => 'Log out',
820 -'userlogout' => 'Log out',
821 -'notloggedin' => 'Not logged in',
822 -'nologin' => 'Don\'t have a login? $1.',
823 -'nologinlink' => 'Create an account',
824 -'createaccount' => 'Create account',
825 -'gotaccount' => 'Already have an account? $1.',
826 -'gotaccountlink' => 'Log in',
827 -'createaccountmail' => 'by e-mail',
828 -'badretype' => 'The passwords you entered do not match.',
829 -'userexists' => 'Username entered already in use. Please choose a different name.',
830 -'youremail' => 'E-mail:',
831 -'username' => 'Username:',
832 -'uid' => 'User ID:',
833 -'yourrealname' => 'Real name:',
834 -'yourlanguage' => 'Language:',
835 -'yourvariant' => 'Variant',
836 -'yournick' => 'Nickname:',
837 -'badsig' => 'Invalid raw signature; check HTML tags.',
838 -'email' => 'E-mail',
839 -'prefs-help-realname' => 'Real name is optional and if you choose to provide it this will be used for giving you attribution for your work.',
840 -'loginerror' => 'Login error',
841 -'prefs-help-email' => 'E-mail address is optional, but it enables others to contact you through your user or user_talk page without needing to reveal your identity.',
842 -'nocookiesnew' => 'The user account was created, but you are not logged in. {{SITENAME}} uses cookies to log in users. You have cookies disabled. Please enable them, then log in with your new username and password.',
843 -'nocookieslogin' => '{{SITENAME}} uses cookies to log in users. You have cookies disabled. Please enable them and try again.',
844 -'noname' => 'You have not specified a valid user name.',
845 -'loginsuccesstitle' => 'Login successful',
846 -'loginsuccess' => "'''You are now logged in to {{SITENAME}} as \"$1\".'''",
847 -'nosuchuser' => 'There is no user by the name "$1". Check your spelling, or create a new account.',
848 -'nosuchusershort' => 'There is no user by the name "$1". Check your spelling.',
849 -'nouserspecified' => 'You have to specify a username.',
850 -'wrongpassword' => 'Incorrect password entered. Please try again.',
851 -'wrongpasswordempty' => 'Password entered was blank. Please try again.',
852 -'mailmypassword' => 'E-mail password',
853 -'passwordremindertitle' => 'Password reminder from {{SITENAME}}',
854 -'passwordremindertext' => 'Someone (probably you, from IP address $1)
 803+'loginpagetitle' => 'User login',
 804+'yourname' => 'Username:',
 805+'yourpassword' => 'Password:',
 806+'yourpasswordagain' => 'Retype password:',
 807+'remembermypassword' => 'Remember my login on this computer',
 808+'yourdomainname' => 'Your domain:',
 809+'externaldberror' => 'There was either an external authentication database error or you are not allowed to update your external account.',
 810+'loginproblem' => '<b>There has been a problem with your login.</b><br />Try again!',
 811+'alreadyloggedin' => '<strong>User $1, you are already logged in!</strong><br />',
 812+'login' => 'Log in',
 813+'loginprompt' => 'You must have cookies enabled to log in to {{SITENAME}}.',
 814+'userlogin' => 'Log in / create account',
 815+'logout' => 'Log out',
 816+'userlogout' => 'Log out',
 817+'notloggedin' => 'Not logged in',
 818+'nologin' => "Don't have a login? $1.",
 819+'nologinlink' => 'Create an account',
 820+'createaccount' => 'Create account',
 821+'gotaccount' => 'Already have an account? $1.',
 822+'gotaccountlink' => 'Log in',
 823+'createaccountmail' => 'by e-mail',
 824+'badretype' => 'The passwords you entered do not match.',
 825+'userexists' => 'Username entered already in use. Please choose a different name.',
 826+'youremail' => 'E-mail:',
 827+'username' => 'Username:',
 828+'uid' => 'User ID:',
 829+'yourrealname' => 'Real name:',
 830+'yourlanguage' => 'Language:',
 831+'yourvariant' => 'Variant',
 832+'yournick' => 'Nickname:',
 833+'badsig' => 'Invalid raw signature; check HTML tags.',
 834+'badsiglength' => 'Nickname too long; must be under $1 characters.',
 835+'email' => 'E-mail',
 836+'prefs-help-realname' => 'Real name is optional and if you choose to provide it this will be used for giving you attribution for your work.',
 837+'loginerror' => 'Login error',
 838+'prefs-help-email' => 'E-mail address is optional, but it enables others to contact you through your user or user_talk page without needing to reveal your identity.',
 839+'nocookiesnew' => 'The user account was created, but you are not logged in. {{SITENAME}} uses cookies to log in users. You have cookies disabled. Please enable them, then log in with your new username and password.',
 840+'nocookieslogin' => '{{SITENAME}} uses cookies to log in users. You have cookies disabled. Please enable them and try again.',
 841+'noname' => 'You have not specified a valid user name.',
 842+'loginsuccesstitle' => 'Login successful',
 843+'loginsuccess' => "'''You are now logged in to {{SITENAME}} as \"\$1\".'''",
 844+'nosuchuser' => 'There is no user by the name "$1". Check your spelling, or create a new account.',
 845+'nosuchusershort' => 'There is no user by the name "$1". Check your spelling.',
 846+'nouserspecified' => 'You have to specify a username.',
 847+'wrongpassword' => 'Incorrect password entered. Please try again.',
 848+'wrongpasswordempty' => 'Password entered was blank. Please try again.',
 849+'mailmypassword' => 'E-mail password',
 850+'passwordremindertitle' => 'Password reminder from {{SITENAME}}',
 851+'passwordremindertext' => 'Someone (probably you, from IP address $1)
855852 requested that we send you a new password for {{SITENAME}} ($4).
856853 The password for user "$2" is now "$3".
857854 You should log in and change your password now.
@@ -858,94 +855,94 @@
859856 If someone else made this request or if you have remembered your password and
860857 you no longer wish to change it, you may ignore this message and continue using
861858 your old password.',
862 -'noemail' => 'There is no e-mail address recorded for user "$1".',
863 -'passwordsent' => 'A new password has been sent to the e-mail address
 859+'noemail' => 'There is no e-mail address recorded for user "$1".',
 860+'passwordsent' => 'A new password has been sent to the e-mail address
864861 registered for "$1".
865862 Please log in again after you receive it.',
866 -'blocked-mailpassword' => 'Your IP address is blocked from editing, and so
 863+'blocked-mailpassword' => 'Your IP address is blocked from editing, and so
867864 is not allowed to use the password recovery function to prevent abuse.',
868 -'eauthentsent' => 'A confirmation e-mail has been sent to the nominated e-mail address.
 865+'eauthentsent' => 'A confirmation e-mail has been sent to the nominated e-mail address.
869866 Before any other mail is sent to the account, you will have to follow the instructions in the e-mail,
870867 to confirm that the account is actually yours.',
871 -'throttled-mailpassword' => 'A password reminder has already been sent, within the
 868+'throttled-mailpassword' => 'A password reminder has already been sent, within the
872869 last $1 hours. To prevent abuse, only one password reminder will be sent per
873870 $1 hours.',
874 -'loginend' => '',
875 -'signupend' => '{{int:loginend}}',
876 -'mailerror' => 'Error sending mail: $1',
877 -'acct_creation_throttle_hit' => 'Sorry, you have already created $1 accounts. You can\'t make any more.',
878 -'emailauthenticated' => 'Your e-mail address was authenticated on $1.',
879 -'emailnotauthenticated' => 'Your e-mail address is not yet authenticated. No e-mail
 871+'loginend' => '', # don't translate or duplicate this message to other languages
 872+'signupend' => '{{int:loginend}}', # don't translate or duplicate this message to other languages
 873+'mailerror' => 'Error sending mail: $1',
 874+'acct_creation_throttle_hit' => "Sorry, you have already created $1 accounts. You can't make any more.",
 875+'emailauthenticated' => 'Your e-mail address was authenticated on $1.',
 876+'emailnotauthenticated' => 'Your e-mail address is not yet authenticated. No e-mail
880877 will be sent for any of the following features.',
881 -'noemailprefs' => 'Specify an e-mail address for these features to work.',
882 -'emailconfirmlink' => 'Confirm your e-mail address',
883 -'invalidemailaddress' => 'The e-mail address cannot be accepted as it appears to have an invalid
 878+'noemailprefs' => 'Specify an e-mail address for these features to work.',
 879+'emailconfirmlink' => 'Confirm your e-mail address',
 880+'invalidemailaddress' => 'The e-mail address cannot be accepted as it appears to have an invalid
884881 format. Please enter a well-formatted address or empty that field.',
885 -'accountcreated' => 'Account created',
886 -'accountcreatedtext' => 'The user account for $1 has been created.',
 882+'accountcreated' => 'Account created',
 883+'accountcreatedtext' => 'The user account for $1 has been created.',
887884
888885 # Password reset dialog
889 -'resetpass' => 'Reset account password',
890 -'resetpass_announce' => 'You logged in with a temporary e-mailed code. To finish logging in, you must set a new password here:',
891 -'resetpass_text' => "<!-- Add text here -->",
892 -'resetpass_header' => 'Reset password',
893 -'resetpass_submit' => 'Set password and log in',
894 -'resetpass_success' => 'Your password has been changed successfully! Now logging you in...',
 886+'resetpass' => 'Reset account password',
 887+'resetpass_announce' => 'You logged in with a temporary e-mailed code. To finish logging in, you must set a new password here:',
 888+'resetpass_text' => '<!-- Add text here -->', # only translate this message to other languages if you have to change it
 889+'resetpass_header' => 'Reset password',
 890+'resetpass_submit' => 'Set password and log in',
 891+'resetpass_success' => 'Your password has been changed successfully! Now logging you in...',
895892 'resetpass_bad_temporary' => 'Invalid temporary password. You may have already successfully changed your password or requested a new temporary password.',
896 -'resetpass_forbidden' => 'Passwords cannot be changed on this wiki',
897 -'resetpass_missing' => 'No form data.',
 893+'resetpass_forbidden' => 'Passwords cannot be changed on this wiki',
 894+'resetpass_missing' => 'No form data.',
898895
899 -
900896 # Edit page toolbar
901 -'bold_sample'=>'Bold text',
902 -'bold_tip'=>'Bold text',
903 -'italic_sample'=>'Italic text',
904 -'italic_tip'=>'Italic text',
905 -'link_sample'=>'Link title',
906 -'link_tip'=>'Internal link',
907 -'extlink_sample'=>'http://www.example.com link title',
908 -'extlink_tip'=>'External link (remember http:// prefix)',
909 -'headline_sample'=>'Headline text',
910 -'headline_tip'=>'Level 2 headline',
911 -'math_sample'=>'Insert formula here',
912 -'math_tip'=>'Mathematical formula (LaTeX)',
913 -'nowiki_sample'=>'Insert non-formatted text here',
914 -'nowiki_tip'=>'Ignore wiki formatting',
915 -'image_sample'=>'Example.jpg',
916 -'image_tip'=>'Embedded image',
917 -'media_sample'=>'Example.ogg',
918 -'media_tip'=>'Media file link',
919 -'sig_tip'=>'Your signature with timestamp',
920 -'hr_tip'=>'Horizontal line (use sparingly)',
 897+'bold_sample' => 'Bold text',
 898+'bold_tip' => 'Bold text',
 899+'italic_sample' => 'Italic text',
 900+'italic_tip' => 'Italic text',
 901+'link_sample' => 'Link title',
 902+'link_tip' => 'Internal link',
 903+'extlink_sample' => 'http://www.example.com link title',
 904+'extlink_tip' => 'External link (remember http:// prefix)',
 905+'headline_sample' => 'Headline text',
 906+'headline_tip' => 'Level 2 headline',
 907+'math_sample' => 'Insert formula here',
 908+'math_tip' => 'Mathematical formula (LaTeX)',
 909+'nowiki_sample' => 'Insert non-formatted text here',
 910+'nowiki_tip' => 'Ignore wiki formatting',
 911+'image_sample' => 'Example.jpg',
 912+'image_tip' => 'Embedded image',
 913+'media_sample' => 'Example.ogg',
 914+'media_tip' => 'Media file link',
 915+'sig_tip' => 'Your signature with timestamp',
 916+'hr_tip' => 'Horizontal line (use sparingly)',
921917
922918 # Edit pages
923 -#
924 -'summary' => 'Summary',
925 -'subject' => 'Subject/headline',
926 -'minoredit' => 'This is a minor edit',
927 -'watchthis' => 'Watch this page',
928 -'savearticle' => 'Save page',
929 -'preview' => 'Preview',
930 -'showpreview' => 'Show preview',
931 -'showlivepreview' => 'Live preview',
932 -'showdiff' => 'Show changes',
933 -'anoneditwarning' => "'''Warning:''' You are not logged in. Your IP address will be recorded in this page's edit history.",
934 -'missingsummary' => "'''Reminder:''' You have not provided an edit summary. If you click Save again, your edit will be saved without one.",
935 -'missingcommenttext' => 'Please enter a comment below.',
936 -'missingcommentheader' => "'''Reminder:''' You have not provided a subject/headline for this comment. If you click Save again, your edit will be saved without one.",
937 -'summary-preview' => 'Summary preview',
938 -'subject-preview' => 'Subject/headline preview',
939 -'blockedtitle' => 'User is blocked',
940 -'blockedtext' => "<big>'''Your user name or IP address has been blocked.'''</big>
 919+'summary' => 'Summary',
 920+'subject' => 'Subject/headline',
 921+'minoredit' => 'This is a minor edit',
 922+'watchthis' => 'Watch this page',
 923+'savearticle' => 'Save page',
 924+'preview' => 'Preview',
 925+'showpreview' => 'Show preview',
 926+'showlivepreview' => 'Live preview',
 927+'showdiff' => 'Show changes',
 928+'anoneditwarning' => "'''Warning:''' You are not logged in. Your IP address will be recorded in this page's edit history.",
 929+'missingsummary' => "'''Reminder:''' You have not provided an edit summary. If you click Save again, your edit will be saved without one.",
 930+'missingcommenttext' => 'Please enter a comment below.',
 931+'missingcommentheader' => "'''Reminder:''' You have not provided a subject/headline for this comment. If you click Save again, your edit will be saved without one.",
 932+'summary-preview' => 'Summary preview',
 933+'subject-preview' => 'Subject/headline preview',
 934+'blockedtitle' => 'User is blocked',
 935+'blockedtext' => "<big>'''Your user name or IP address has been blocked.'''</big>
941936
942937 The block was made by $1. The reason given is ''$2''.
943938
944 -Expiry of block: $6
 939+Expiry of block: $6<br />
 940+Intended blockee: $7
945941
946942 You can contact $1 or another [[{{MediaWiki:grouppage-sysop}}|administrator]] to discuss the block.
947943 You cannot use the 'email this user' feature unless a valid email address is specified in your
948 -[[Special:Preferences|account preferences]]. Your current IP address is $3, and the block ID is #$5. Please include either or both of these in any queries.",
949 -'autoblockedtext' => 'Your IP address has been automatically blocked because it was used by another user, who was blocked by $1.
 944+[[Special:Preferences|account preferences]] and you have not been blocked from using it.
 945+Your current IP address is $3, and the block ID is #$5. Please include either or both of these in any queries.",
 946+'autoblockedtext' => 'Your IP address has been automatically blocked because it was used by another user, who was blocked by $1.
950947 The reason given is this:
951948
952949 :\'\'$2\'\'
@@ -955,154 +952,155 @@
956953 You may contact $1 or one of the other
957954 [[{{MediaWiki:grouppage-sysop}}|administrators]] to discuss the block.
958955
959 -Note that you may not use the "e-mail this user" feature unless you have a valid e-mail address registered in your [[Special:Preferences|user preferences]].
 956+Note that you may not use the "e-mail this user" feature unless you have a valid e-mail address
 957+registered in your [[Special:Preferences|user preferences]] and you have not been blocked from using it.
960958
961959 Your block ID is $5. Please include this ID in any queries you make.',
962 -'blockedoriginalsource' => "The source of '''$1''' is shown below:",
963 -'blockededitsource' => "The text of '''your edits''' to '''$1''' is shown below:",
964 -'whitelistedittitle' => 'Login required to edit',
965 -'whitelistedittext' => 'You have to $1 to edit pages.',
966 -'whitelistreadtitle' => 'Login required to read',
967 -'whitelistreadtext' => 'You have to [[Special:Userlogin|login]] to read pages.',
968 -'whitelistacctitle' => 'You are not allowed to create an account',
969 -'whitelistacctext' => 'To be allowed to create accounts in this wiki you have to [[Special:Userlogin|log]] in and have the appropriate permissions.',
970 -'confirmedittitle' => 'E-mail confirmation required to edit',
971 -'confirmedittext' => 'You must confirm your e-mail address before editing pages. Please set and validate your e-mail address through your [[Special:Preferences|user preferences]].',
972 -'nosuchsectiontitle' => 'No such section',
973 -'nosuchsectiontext' => "You tried to edit a section that doesn't exist. Since there is no section \$1, there's no place to save your edit.",
974 -'loginreqtitle' => 'Login Required',
975 -'loginreqlink' => 'log in',
976 -'loginreqpagetext' => 'You must $1 to view other pages.',
977 -'accmailtitle' => 'Password sent.',
978 -'accmailtext' => 'The password for "$1" has been sent to $2.',
979 -'newarticle' => '(New)',
980 -'newarticletext' =>
981 -"You've followed a link to a page that doesn't exist yet.
 960+'blockedoriginalsource' => "The source of '''$1''' is shown below:",
 961+'blockededitsource' => "The text of '''your edits''' to '''$1''' is shown below:",
 962+'whitelistedittitle' => 'Login required to edit',
 963+'whitelistedittext' => 'You have to $1 to edit pages.',
 964+'whitelistreadtitle' => 'Login required to read',
 965+'whitelistreadtext' => 'You have to [[Special:Userlogin|login]] to read pages.',
 966+'whitelistacctitle' => 'You are not allowed to create an account',
 967+'whitelistacctext' => 'To be allowed to create accounts in this wiki you have to [[Special:Userlogin|log]] in and have the appropriate permissions.',
 968+'confirmedittitle' => 'E-mail confirmation required to edit',
 969+'confirmedittext' => 'You must confirm your e-mail address before editing pages. Please set and validate your e-mail address through your [[Special:Preferences|user preferences]].',
 970+'nosuchsectiontitle' => 'No such section',
 971+'nosuchsectiontext' => "You tried to edit a section that doesn't exist. Since there is no section $1, there's no place to save your edit.",
 972+'loginreqtitle' => 'Login Required',
 973+'loginreqlink' => 'log in',
 974+'loginreqpagetext' => 'You must $1 to view other pages.',
 975+'accmailtitle' => 'Password sent.',
 976+'accmailtext' => 'The password for "$1" has been sent to $2.',
 977+'newarticle' => '(New)',
 978+'newarticletext' => "You've followed a link to a page that doesn't exist yet.
982979 To create the page, start typing in the box below
983980 (see the [[{{MediaWiki:helppage}}|help page]] for more info).
984981 If you are here by mistake, just click your browser's '''back''' button.",
985 -'newarticletextanon' => '{{int:newarticletext}}',
986 -'talkpagetext' => '<!-- MediaWiki:talkpagetext -->',
987 -'anontalkpagetext' => "----''This is the discussion page for an anonymous user who has not created an account yet or who does not use it. We therefore have to use the numerical IP address to identify him/her. Such an IP address can be shared by several users. If you are an anonymous user and feel that irrelevant comments have been directed at you, please [[Special:Userlogin|create an account or log in]] to avoid future confusion with other anonymous users.''",
988 -'noarticletext' => 'There is currently no text in this page, you can [[Special:Search/{{PAGENAME}}|search for this page title]] in other pages or [{{fullurl:{{FULLPAGENAME}}|action=edit}} edit this page].',
989 -'noarticletextanon' => '{{int:noarticletext}}',
990 -'clearyourcache' => "'''Note:''' After saving, you may have to bypass your browser's cache to see the changes. '''Mozilla / Firefox / Safari:''' hold down ''Shift'' while clicking ''Reload'', or press ''Ctrl-Shift-R'' (''Cmd-Shift-R'' on Apple Mac); '''IE:''' hold ''Ctrl'' while clicking ''Refresh'', or press ''Ctrl-F5''; '''Konqueror:''': simply click the ''Reload'' button, or press ''F5''; '''Opera''' users may need to completely clear their cache in ''Tools→Preferences''.",
991 -'usercssjsyoucanpreview' => '<strong>Tip:</strong> Use the \'Show preview\' button to test your new CSS/JS before saving.',
992 -'usercsspreview' => '\'\'\'Remember that you are only previewing your user CSS, it has not yet been saved!\'\'\'',
993 -'userjspreview' => '\'\'\'Remember that you are only testing/previewing your user JavaScript, it has not yet been saved!\'\'\'',
994 -'userinvalidcssjstitle' => "'''Warning:''' There is no skin \"$1\". Remember that custom .css and .js pages use a lowercase title, e.g. {{ns:user}}:Foo/monobook.css as opposed to {{ns:user}}:Foo/Monobook.css.",
995 -'updated' => '(Updated)',
996 -'note' => '<strong>Note:</strong>',
997 -'previewnote' => '<strong>This is only a preview; changes have not yet been saved!</strong>',
998 -'session_fail_preview' => '<strong>Sorry! We could not process your edit due to a loss of session data.
999 -Please try again. If it still doesn\'t work, try logging out and logging back in.</strong>',
1000 -'previewconflict' => 'This preview reflects the text in the upper text editing area as it will appear if you choose to save.',
1001 -'session_fail_preview_html' => '<strong>Sorry! We could not process your edit due to a loss of session data.</strong>
 982+'newarticletextanon' => '{{int:newarticletext}}', # don't translate or duplicate this message to other languages
 983+'talkpagetext' => '<!-- MediaWiki:talkpagetext -->', # don't translate or duplicate this message to other languages
 984+'anontalkpagetext' => "----''This is the discussion page for an anonymous user who has not created an account yet or who does not use it. We therefore have to use the numerical IP address to identify him/her. Such an IP address can be shared by several users. If you are an anonymous user and feel that irrelevant comments have been directed at you, please [[Special:Userlogin|create an account or log in]] to avoid future confusion with other anonymous users.''",
 985+'noarticletext' => 'There is currently no text in this page, you can [[Special:Search/{{PAGENAME}}|search for this page title]] in other pages or [{{fullurl:{{FULLPAGENAME}}|action=edit}} edit this page].',
 986+'noarticletextanon' => '{{int:noarticletext}}', # don't translate or duplicate this message to other languages
 987+'clearyourcache' => "'''Note:''' After saving, you may have to bypass your browser's cache to see the changes. '''Mozilla / Firefox / Safari:''' hold down ''Shift'' while clicking ''Reload'', or press ''Ctrl-Shift-R'' (''Cmd-Shift-R'' on Apple Mac); '''IE:''' hold ''Ctrl'' while clicking ''Refresh'', or press ''Ctrl-F5''; '''Konqueror:''': simply click the ''Reload'' button, or press ''F5''; '''Opera''' users may need to completely clear their cache in ''Tools→Preferences''.",
 988+'usercssjsyoucanpreview' => "<strong>Tip:</strong> Use the 'Show preview' button to test your new CSS/JS before saving.",
 989+'usercsspreview' => "'''Remember that you are only previewing your user CSS, it has not yet been saved!'''",
 990+'userjspreview' => "'''Remember that you are only testing/previewing your user JavaScript, it has not yet been saved!'''",
 991+'userinvalidcssjstitle' => "'''Warning:''' There is no skin \"\$1\". Remember that custom .css and .js pages use a lowercase title, e.g. {{ns:user}}:Foo/monobook.css as opposed to {{ns:user}}:Foo/Monobook.css.",
 992+'updated' => '(Updated)',
 993+'note' => '<strong>Note:</strong>',
 994+'previewnote' => '<strong>This is only a preview; changes have not yet been saved!</strong>',
 995+'previewconflict' => 'This preview reflects the text in the upper text editing area as it will appear if you choose to save.',
 996+'session_fail_preview' => "<strong>Sorry! We could not process your edit due to a loss of session data.
 997+Please try again. If it still doesn't work, try logging out and logging back in.</strong>",
 998+'session_fail_preview_html' => "<strong>Sorry! We could not process your edit due to a loss of session data.</strong>
1002999
1003 -\'\'Because this wiki has raw HTML enabled, the preview is hidden as a precaution against JavaScript attacks.\'\'
 1000+''Because this wiki has raw HTML enabled, the preview is hidden as a precaution against JavaScript attacks.''
10041001
1005 -<strong>If this is a legitimate edit attempt, please try again. If it still doesn\'t work, try logging out and logging back in.</strong>',
1006 -'importing' => 'Importing $1',
1007 -'editing' => 'Editing $1',
1008 -'editinguser' => 'Editing user <b>$1</b>',
1009 -'editingsection' => 'Editing $1 (section)',
1010 -'editingcomment' => 'Editing $1 (comment)',
1011 -'editconflict' => 'Edit conflict: $1',
1012 -'explainconflict' => 'Someone else has changed this page since you started editing it.
 1002+<strong>If this is a legitimate edit attempt, please try again. If it still doesn't work, try logging out and logging back in.</strong>",
 1003+'importing' => 'Importing $1',
 1004+'editing' => 'Editing $1',
 1005+'editinguser' => 'Editing user <b>$1</b>',
 1006+'editingsection' => 'Editing $1 (section)',
 1007+'editingcomment' => 'Editing $1 (comment)',
 1008+'editconflict' => 'Edit conflict: $1',
 1009+'explainconflict' => 'Someone else has changed this page since you started editing it.
10131010 The upper text area contains the page text as it currently exists.
10141011 Your changes are shown in the lower text area.
10151012 You will have to merge your changes into the existing text.
10161013 <b>Only</b> the text in the upper text area will be saved when you
10171014 press "Save page".<br />',
1018 -'yourtext' => 'Your text',
1019 -'storedversion' => 'Stored version',
1020 -'nonunicodebrowser' => "<strong>WARNING: Your browser is not unicode compliant. A workaround is in place to allow you to safely edit articles: non-ASCII characters will appear in the edit box as hexadecimal codes.</strong>",
1021 -'editingold' => "<strong>WARNING: You are editing an out-of-date
 1015+'yourtext' => 'Your text',
 1016+'storedversion' => 'Stored version',
 1017+'nonunicodebrowser' => '<strong>WARNING: Your browser is not unicode compliant. A workaround is in place to allow you to safely edit articles: non-ASCII characters will appear in the edit box as hexadecimal codes.</strong>',
 1018+'editingold' => '<strong>WARNING: You are editing an out-of-date
10221019 revision of this page.
1023 -If you save it, any changes made since this revision will be lost.</strong>",
1024 -'yourdiff' => 'Differences',
1025 -'copyrightwarning' => 'Please note that all contributions to {{SITENAME}} are considered to be released under the $2 (see $1 for details). If you don\'t want your writing to be edited mercilessly and redistributed at will, then don\'t submit it here.<br />
 1020+If you save it, any changes made since this revision will be lost.</strong>',
 1021+'yourdiff' => 'Differences',
 1022+'copyrightwarning' => "Please note that all contributions to {{SITENAME}} are considered to be released under the $2 (see $1 for details). If you don't want your writing to be edited mercilessly and redistributed at will, then don't submit it here.<br />
10261023 You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
1027 -<strong>DO NOT SUBMIT COPYRIGHTED WORK WITHOUT PERMISSION!</strong>',
1028 -'copyrightwarning2' => 'Please note that all contributions to {{SITENAME}} may be edited, altered, or removed by other contributors. If you don\'t want your writing to be edited mercilessly, then don\'t submit it here.<br />
 1024+<strong>DO NOT SUBMIT COPYRIGHTED WORK WITHOUT PERMISSION!</strong>",
 1025+'copyrightwarning2' => "Please note that all contributions to {{SITENAME}} may be edited, altered, or removed by other contributors. If you don't want your writing to be edited mercilessly, then don't submit it here.<br />
10291026 You are also promising us that you wrote this yourself, or copied it from a
10301027 public domain or similar free resource (see $1 for details).
1031 -<strong>DO NOT SUBMIT COPYRIGHTED WORK WITHOUT PERMISSION!</strong>',
1032 -'longpagewarning' => "<strong>WARNING: This page is $1 kilobytes long; some
 1028+<strong>DO NOT SUBMIT COPYRIGHTED WORK WITHOUT PERMISSION!</strong>",
 1029+'longpagewarning' => '<strong>WARNING: This page is $1 kilobytes long; some
10331030 browsers may have problems editing pages approaching or longer than 32kb.
1034 -Please consider breaking the page into smaller sections.</strong>",
1035 -'longpageerror' => "<strong>ERROR: The text you have submitted is $1 kilobytes
1036 -long, which is longer than the maximum of $2 kilobytes. It cannot be saved.</strong>",
1037 -'readonlywarning' => '<strong>WARNING: The database has been locked for maintenance,
 1031+Please consider breaking the page into smaller sections.</strong>',
 1032+'longpageerror' => '<strong>ERROR: The text you have submitted is $1 kilobytes
 1033+long, which is longer than the maximum of $2 kilobytes. It cannot be saved.</strong>',
 1034+'readonlywarning' => '<strong>WARNING: The database has been locked for maintenance,
10381035 so you will not be able to save your edits right now. You may wish to cut-n-paste
10391036 the text into a text file and save it for later.</strong>',
1040 -'protectedpagewarning' => "<strong>WARNING: This page has been locked so that only users with sysop privileges can edit it.</strong>",
1041 -'semiprotectedpagewarning' => "'''Note:''' This page has been locked so that only registered users can edit it.",
1042 -'cascadeprotectedwarning' => "'''Warning:''' This page has been locked so that only users with sysop privileges can edit it, because it is included in the following cascade-protected {{PLURAL:$1|page|pages}}:",
1043 -'templatesused' => 'Templates used on this page:',
1044 -'templatesusedpreview' => 'Templates used in this preview:',
1045 -'templatesusedsection' => 'Templates used in this section:',
1046 -'template-protected' => '(protected)',
1047 -'template-semiprotected' => '(semi-protected)',
1048 -'edittools' => '<!-- Text here will be shown below edit and upload forms. -->',
1049 -'nocreatetitle' => 'Page creation limited',
1050 -'nocreatetext' => 'This site has restricted the ability to create new pages.
 1037+'protectedpagewarning' => '<strong>WARNING: This page has been locked so that only users with sysop privileges can edit it.</strong>',
 1038+'semiprotectedpagewarning' => "'''Note:''' This page has been locked so that only registered users can edit it.",
 1039+'cascadeprotectedwarning' => "'''Warning:''' This page has been locked so that only users with sysop privileges can edit it, because it is included in the following cascade-protected {{PLURAL:$1|page|pages}}:",
 1040+'templatesused' => 'Templates used on this page:',
 1041+'templatesusedpreview' => 'Templates used in this preview:',
 1042+'templatesusedsection' => 'Templates used in this section:',
 1043+'template-protected' => '(protected)',
 1044+'template-semiprotected' => '(semi-protected)',
 1045+'edittools' => '<!-- Text here will be shown below edit and upload forms. -->',
 1046+'nocreatetitle' => 'Page creation limited',
 1047+'nocreatetext' => 'This site has restricted the ability to create new pages.
10511048 You can go back and edit an existing page, or [[Special:Userlogin|log in or create an account]].',
 1049+'recreate-deleted-warn' => "'''Warning: You are recreating a page that was previously deleted.'''
10521050
 1051+You should consider whether it is appropriate to continue editing this page.
 1052+The deletion log for this page is provided here for convenience:",
 1053+
10531054 # "Undo" feature
10541055 'undo-success' => 'The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.',
10551056 'undo-failure' => 'The edit could not be undone due to conflicting intermediate edits.',
10561057 'undo-summary' => 'Undo revision $1 by [[Special:Contributions/$2|$2]] ([[User talk:$2|Talk]])',
10571058
10581059 # Account creation failure
1059 -'cantcreateaccounttitle' => 'Can\'t create account',
1060 -'cantcreateaccounttext' => 'Account creation from this IP address (<b>$1</b>) has been blocked.
 1060+'cantcreateaccounttitle' => "Can't create account",
 1061+'cantcreateaccounttext' => 'Account creation from this IP address (<b>$1</b>) has been blocked.
10611062 This is probably due to persistent vandalism from your school or Internet service
10621063 provider.',
10631064
10641065 # History pages
1065 -#
1066 -'revhistory' => 'Revision history',
1067 -'viewpagelogs' => 'View logs for this page',
1068 -'nohistory' => 'There is no edit history for this page.',
1069 -'revnotfound' => 'Revision not found',
1070 -'revnotfoundtext' => "The old revision of the page you asked for could not be found.
1071 -Please check the URL you used to access this page.",
1072 -'loadhist' => 'Loading page history',
1073 -'currentrev' => 'Current revision',
1074 -'revisionasof' => 'Revision as of $1',
1075 -'revision-info' => 'Revision as of $1 by $2',
1076 -'revision-nav' => '($1) $2 | $3 ($4) | $5 ($6)',
1077 -'previousrevision' => '←Older revision',
1078 -'nextrevision' => 'Newer revision→',
1079 -'currentrevisionlink' => 'Current revision',
1080 -'cur' => 'cur',
1081 -'next' => 'next',
1082 -'last' => 'last',
1083 -'orig' => 'orig',
1084 -'page_first' => 'first',
1085 -'page_last' => 'last',
1086 -'histlegend' => 'Diff selection: mark the radio boxes of the versions to compare and hit enter or the button at the bottom.<br />
 1066+'revhistory' => 'Revision history',
 1067+'viewpagelogs' => 'View logs for this page',
 1068+'nohistory' => 'There is no edit history for this page.',
 1069+'revnotfound' => 'Revision not found',
 1070+'revnotfoundtext' => 'The old revision of the page you asked for could not be found.
 1071+Please check the URL you used to access this page.',
 1072+'loadhist' => 'Loading page history',
 1073+'currentrev' => 'Current revision',
 1074+'revisionasof' => 'Revision as of $1',
 1075+'revision-info' => 'Revision as of $1 by $2',
 1076+'revision-nav' => '($1) $2 | $3 ($4) | $5 ($6)', # don't translate or duplicate this message to other languages
 1077+'previousrevision' => '←Older revision',
 1078+'nextrevision' => 'Newer revision→',
 1079+'currentrevisionlink' => 'Current revision',
 1080+'cur' => 'cur',
 1081+'next' => 'next',
 1082+'last' => 'last',
 1083+'orig' => 'orig',
 1084+'page_first' => 'first',
 1085+'page_last' => 'last',
 1086+'histlegend' => 'Diff selection: mark the radio boxes of the versions to compare and hit enter or the button at the bottom.<br />
10871087 Legend: (cur) = difference with current version,
10881088 (last) = difference with preceding version, M = minor edit.',
1089 -'history_copyright' => '-',
1090 -'deletedrev' => '[deleted]',
1091 -'histfirst' => 'Earliest',
1092 -'histlast' => 'Latest',
1093 -'historysize' => '($1 bytes)',
1094 -'historyempty' => '(empty)',
 1089+'history_copyright' => '-', # don't translate or duplicate this message to other languages
 1090+'deletedrev' => '[deleted]',
 1091+'histfirst' => 'Earliest',
 1092+'histlast' => 'Latest',
 1093+'historysize' => '($1 bytes)',
 1094+'historyempty' => '(empty)',
10951095
10961096 # Revision feed
1097 -#
10981097 'history-feed-title' => 'Revision history',
10991098 'history-feed-description' => 'Revision history for this page on the wiki',
11001099 'history-feed-item-nocomment' => '$1 at $2', # user at time
1101 -'history-feed-empty' => 'The requested page doesn\'t exist.
 1100+'history-feed-empty' => "The requested page doesn't exist.
11021101 It may have been deleted from the wiki, or renamed.
1103 -Try [[Special:Search|searching on the wiki]] for relevant new pages.',
 1102+Try [[Special:Search|searching on the wiki]] for relevant new pages.",
11041103
11051104 # Revision deletion
1106 -#
11071105 'rev-deleted-comment' => '(comment removed)',
11081106 'rev-deleted-user' => '(username removed)',
11091107 'rev-deleted-event' => '(entry removed)',
@@ -1119,19 +1117,19 @@
11201118 'revisiondelete' => 'Delete/undelete revisions',
11211119 'revdelete-nooldid-title' => 'No target revision',
11221120 'revdelete-nooldid-text' => 'You have either not specified a target revision(s) to perform this
1123 -function on or the specified revision does not exist.',
1124 -'revdelete-selected' => "{{PLURAL:$2|Selected revision|Selected revisions}} of '''$1:'''",
1125 -'logdelete-selected' => "{{PLURAL:$2|Selected log event|Selected log events}} for '''$1:'''",
1126 -'revdelete-text' => "Deleted revisions and events will still appear in the page history and logs,
 1121+function, the specified revision does not exist, or you are attempting to hide the current revision.',
 1122+'revdelete-selected' => "{{PLURAL:$2|Selected revision|Selected revisions}} of '''[[$1]]''':",
 1123+'logdelete-selected' => "{{PLURAL:$2|Selected log event|Selected log events}} for '''$1''':",
 1124+'revdelete-text' => 'Deleted revisions and events will still appear in the page history and logs,
11271125 but parts of their content will be inaccessible to the public.
11281126
11291127 Other admins on this wiki will still be able to access the hidden content and can
1130 -undelete it again through this same interface, unless additional restrictions are set.",
 1128+undelete it again through this same interface, unless additional restrictions are set.',
11311129 'revdelete-legend' => 'Set restrictions:',
11321130 'revdelete-hide-text' => 'Hide revision text',
11331131 'revdelete-hide-name' => 'Hide action and target',
11341132 'revdelete-hide-comment' => 'Hide edit comment',
1135 -'revdelete-hide-user' => 'Hide editor\'s username/IP',
 1133+'revdelete-hide-user' => "Hide editor's username/IP",
11361134 'revdelete-hide-restricted' => 'Apply these restrictions to Sysops and lock this interface',
11371135 'revdelete-suppress' => 'Suppress data from sysops as well as others',
11381136 'revdelete-hide-image' => 'Hide file content',
@@ -1142,12 +1140,11 @@
11431141 'logdelete-logentry' => 'changed event visibility of [[$1]]',
11441142 'revdelete-logaction' => '$1 {{PLURAL:$1|revision|revisions}} set to mode $2',
11451143 'logdelete-logaction' => '$1 {{PLURAL:$1|event|events}} to [[$3]] set to mode $2',
1146 -'revdelete-success' => 'Revision visibility successfully set.',
1147 -'logdelete-success' => 'Event visibility successfully set.',
 1144+'revdelete-success' => "'''Revision visibility successfully set.'''",
 1145+'logdelete-success' => "'''Event visibility successfully set.'''",
11481146
11491147 # Oversight log
1150 -#
1151 -'oversightlog' => 'Oversight log',
 1148+'oversightlog' => 'Oversight log',
11521149 'overlogpagetext' => 'Below is a list of the most recent deletions and blocks involving items
11531150 hidden from Sysops. Automatically blocked IP addresses are not listed. See the [[Special:Ipblocklist|IP block list]]
11541151 for the list of currently operational bans and blocks. Note that deleted pages listed here will not be listed using
@@ -1157,51 +1154,48 @@
11581155 will remain hidden only as long as they are blocked.',
11591156
11601157 # Diffs
1161 -#
1162 -'difference' => '(Difference between revisions)',
1163 -'loadingrev' => 'loading revision for diff',
1164 -'lineno' => "Line $1:",
1165 -'editcurrent' => 'Edit the current version of this page',
 1158+'difference' => '(Difference between revisions)',
 1159+'loadingrev' => 'loading revision for diff',
 1160+'lineno' => 'Line $1:',
 1161+'editcurrent' => 'Edit the current version of this page',
11661162 'selectnewerversionfordiff' => 'Select a newer version for comparison',
11671163 'selectolderversionfordiff' => 'Select an older version for comparison',
1168 -'compareselectedversions' => 'Compare selected versions',
1169 -'editundo' => 'undo',
1170 -'diff-multi' => "({{PLURAL:$1|One intermediate revision|$1 intermediate revisions}} not shown.)",
 1164+'compareselectedversions' => 'Compare selected versions',
 1165+'editundo' => 'undo',
 1166+'diff-multi' => '({{PLURAL:$1|One intermediate revision|$1 intermediate revisions}} not shown.)',
11711167
11721168 # Search results
1173 -#
1174 -'searchresults' => 'Search results',
1175 -'searchresulttext' => "For more information about searching {{SITENAME}}, see [[{{MediaWiki:helppage}}|{{int:help}}]].",
1176 -'searchsubtitle' => "You searched for '''[[:$1]]'''",
 1169+'searchresults' => 'Search results',
 1170+'searchresulttext' => 'For more information about searching {{SITENAME}}, see [[{{MediaWiki:helppage}}|{{int:help}}]].',
 1171+'searchsubtitle' => "You searched for '''[[:$1]]'''",
11771172 'searchsubtitleinvalid' => "You searched for '''$1'''",
1178 -'badquery' => 'Badly formed search query',
1179 -'badquerytext' => 'We could not process your query.
 1173+'badquery' => 'Badly formed search query',
 1174+'badquerytext' => 'We could not process your query.
11801175 This is probably because you have attempted to search for a
11811176 word fewer than three letters long, which is not yet supported.
11821177 It could also be that you have mistyped the expression, for
11831178 example "fish and and scales".
11841179 Please try another query.',
1185 -'matchtotals' => "The query \"$1\" matched $2 page titles
1186 -and the text of $3 pages.",
1187 -'noexactmatch' => "'''There is no page titled \"$1\".''' You can [[:$1|create this page]].",
1188 -'titlematches' => 'Article title matches',
1189 -'notitlematches' => 'No page title matches',
1190 -'textmatches' => 'Page text matches',
1191 -'notextmatches' => 'No page text matches',
1192 -'prevn' => "previous $1",
1193 -'nextn' => "next $1",
1194 -'viewprevnext' => "View ($1) ($2) ($3).",
1195 -'showingresults' => "Showing below up to {{PLURAL:$1|'''1''' result|'''$1''' results}} starting with #'''$2'''.",
1196 -'showingresultsnum' => "Showing below {{PLURAL:$3|'''1''' result|'''$3''' results}} starting with #'''$2'''.",
1197 -'nonefound' => "'''Note''': Unsuccessful searches are
 1180+'matchtotals' => 'The query "$1" matched $2 page titles
 1181+and the text of $3 pages.',
 1182+'noexactmatch' => "'''There is no page titled \"\$1\".''' You can [[:\$1|create this page]].",
 1183+'titlematches' => 'Article title matches',
 1184+'notitlematches' => 'No page title matches',
 1185+'textmatches' => 'Page text matches',
 1186+'notextmatches' => 'No page text matches',
 1187+'prevn' => 'previous $1',
 1188+'nextn' => 'next $1',
 1189+'viewprevnext' => 'View ($1) ($2) ($3).',
 1190+'showingresults' => "Showing below up to {{PLURAL:$1|'''1''' result|'''$1''' results}} starting with #'''$2'''.",
 1191+'showingresultsnum' => "Showing below {{PLURAL:$3|'''1''' result|'''$3''' results}} starting with #'''$2'''.",
 1192+'nonefound' => "'''Note''': Unsuccessful searches are
11981193 often caused by searching for common words like \"have\" and \"from\",
11991194 which are not indexed, or by specifying more than one search term (only pages
12001195 containing all of the search terms will appear in the result).",
1201 -'powersearch' => 'Search',
1202 -'powersearchtext' => "Search in namespaces:<br />$1<br />$2 List redirects<br />Search for $3 $9",
1203 -'searchdisabled' => '{{SITENAME}} search is disabled. You can search via Google in the meantime. Note that their indexes of {{SITENAME}} content may be out of date.',
1204 -
1205 -'googlesearch' => '
 1196+'powersearch' => 'Search',
 1197+'powersearchtext' => 'Search in namespaces:<br />$1<br />$2 List redirects<br />Search for $3 $9',
 1198+'searchdisabled' => '{{SITENAME}} search is disabled. You can search via Google in the meantime. Note that their indexes of {{SITENAME}} content may be out of date.',
 1199+'googlesearch' => '
12061200 <form method="get" action="http://www.google.com/search" id="googlesearch">
12071201 <input type="hidden" name="domains" value="{{SERVER}}" />
12081202 <input type="hidden" name="num" value="50" />
@@ -1214,96 +1208,95 @@
12151209 <input type="radio" name="sitesearch" id="gwiki" value="{{SERVER}}" checked="checked" /><label for="gwiki">{{SITENAME}}</label>
12161210 <input type="radio" name="sitesearch" id="gWWW" value="" /><label for="gWWW">WWW</label>
12171211 </div>
1218 -</form>',
1219 -'blanknamespace' => '(Main)',
 1212+</form>', # don't translate or duplicate this message to other languages
 1213+'blanknamespace' => '(Main)',
12201214
12211215 # Preferences page
1222 -#
1223 -'preferences' => 'Preferences',
1224 -'preferences-summary' => '',
1225 -'mypreferences' => 'My preferences',
1226 -'prefsnologin' => 'Not logged in',
1227 -'prefsnologintext' => "You must be [[Special:Userlogin|logged in]] to set user preferences.",
1228 -'prefsreset' => 'Preferences have been reset from storage.',
1229 -'qbsettings' => 'Quickbar',
1230 -'qbsettings-none' => 'None',
1231 -'qbsettings-fixedleft' => 'Fixed left',
1232 -'qbsettings-fixedright' => 'Fixed right',
1233 -'qbsettings-floatingleft' => 'Floating left',
1234 -'qbsettings-floatingright' => 'Floating right',
1235 -'changepassword' => 'Change password',
1236 -'skin' => 'Skin',
1237 -'math' => 'Math',
1238 -'dateformat' => 'Date format',
1239 -'datedefault' => 'No preference',
1240 -'datetime' => 'Date and time',
1241 -'math_failure' => 'Failed to parse',
1242 -'math_unknown_error' => 'unknown error',
1243 -'math_unknown_function' => 'unknown function',
1244 -'math_lexing_error' => 'lexing error',
1245 -'math_syntax_error' => 'syntax error',
1246 -'math_image_error' => 'PNG conversion failed; check for correct installation of latex, dvips, gs, and convert',
1247 -'math_bad_tmpdir' => 'Can\'t write to or create math temp directory',
1248 -'math_bad_output' => 'Can\'t write to or create math output directory',
1249 -'math_notexvc' => 'Missing texvc executable; please see math/README to configure.',
1250 -'prefs-personal' => 'User profile',
1251 -'prefs-rc' => 'Recent changes',
1252 -'prefs-watchlist' => 'Watchlist',
1253 -'prefs-watchlist-days' => 'Number of days to show in watchlist:',
1254 -'prefs-watchlist-edits' => 'Number of edits to show in expanded watchlist:',
1255 -'prefs-misc' => 'Misc',
1256 -'saveprefs' => 'Save',
1257 -'resetprefs' => 'Reset',
1258 -'oldpassword' => 'Old password:',
1259 -'newpassword' => 'New password:',
1260 -'retypenew' => 'Retype new password:',
1261 -'textboxsize' => 'Editing',
1262 -'rows' => 'Rows:',
1263 -'columns' => 'Columns:',
1264 -'searchresultshead' => 'Search',
1265 -'resultsperpage' => 'Hits per page:',
1266 -'contextlines' => 'Lines per hit:',
1267 -'contextchars' => 'Context per line:',
1268 -'stubthreshold' => 'Threshold for stub display:',
1269 -'recentchangesdays' => 'Days to show in recent changes:',
1270 -'recentchangescount' => 'Number of edits to show in recent changes:',
1271 -'savedprefs' => 'Your preferences have been saved.',
1272 -'timezonelegend' => 'Time zone',
1273 -'timezonetext' => 'The number of hours your local time differs from server time (UTC).',
1274 -'localtime' => 'Local time',
1275 -'timezoneoffset' => 'Offset¹',
1276 -'servertime' => 'Server time',
1277 -'guesstimezone' => 'Fill in from browser',
1278 -'allowemail' => 'Enable e-mail from other users',
1279 -'defaultns' => 'Search in these namespaces by default:',
1280 -'default' => 'default',
1281 -'files' => 'Files',
 1216+'preferences' => 'Preferences',
 1217+'preferences-summary' => '', # only translate this message to other languages if you have to change it
 1218+'mypreferences' => 'My preferences',
 1219+'prefsnologin' => 'Not logged in',
 1220+'prefsnologintext' => 'You must be [[Special:Userlogin|logged in]] to set user preferences.',
 1221+'prefsreset' => 'Preferences have been reset from storage.',
 1222+'qbsettings' => 'Quickbar',
 1223+'qbsettings-none' => 'None',
 1224+'qbsettings-fixedleft' => 'Fixed left',
 1225+'qbsettings-fixedright' => 'Fixed right',
 1226+'qbsettings-floatingleft' => 'Floating left',
 1227+'qbsettings-floatingright' => 'Floating right',
 1228+'changepassword' => 'Change password',
 1229+'skin' => 'Skin',
 1230+'math' => 'Math',
 1231+'dateformat' => 'Date format',
 1232+'datedefault' => 'No preference',
 1233+'datetime' => 'Date and time',
 1234+'math_failure' => 'Failed to parse',
 1235+'math_unknown_error' => 'unknown error',
 1236+'math_unknown_function' => 'unknown function',
 1237+'math_lexing_error' => 'lexing error',
 1238+'math_syntax_error' => 'syntax error',
 1239+'math_image_error' => 'PNG conversion failed; check for correct installation of latex, dvips, gs, and convert',
 1240+'math_bad_tmpdir' => "Can't write to or create math temp directory",
 1241+'math_bad_output' => "Can't write to or create math output directory",
 1242+'math_notexvc' => 'Missing texvc executable; please see math/README to configure.',
 1243+'prefs-personal' => 'User profile',
 1244+'prefs-rc' => 'Recent changes',
 1245+'prefs-watchlist' => 'Watchlist',
 1246+'prefs-watchlist-days' => 'Number of days to show in watchlist:',
 1247+'prefs-watchlist-edits' => 'Number of edits to show in expanded watchlist:',
 1248+'prefs-misc' => 'Misc',
 1249+'saveprefs' => 'Save',
 1250+'resetprefs' => 'Reset',
 1251+'oldpassword' => 'Old password:',
 1252+'newpassword' => 'New password:',
 1253+'retypenew' => 'Retype new password:',
 1254+'textboxsize' => 'Editing',
 1255+'rows' => 'Rows:',
 1256+'columns' => 'Columns:',
 1257+'searchresultshead' => 'Search',
 1258+'resultsperpage' => 'Hits per page:',
 1259+'contextlines' => 'Lines per hit:',
 1260+'contextchars' => 'Context per line:',
 1261+'stub-threshold' => 'Threshold for <a href="#" class="stub">stub link</a> formatting:',
 1262+'recentchangesdays' => 'Days to show in recent changes:',
 1263+'recentchangescount' => 'Number of edits to show in recent changes:',
 1264+'savedprefs' => 'Your preferences have been saved.',
 1265+'timezonelegend' => 'Time zone',
 1266+'timezonetext' => 'The number of hours your local time differs from server time (UTC).',
 1267+'localtime' => 'Local time',
 1268+'timezoneoffset' => 'Offset¹',
 1269+'servertime' => 'Server time',
 1270+'guesstimezone' => 'Fill in from browser',
 1271+'allowemail' => 'Enable e-mail from other users',
 1272+'defaultns' => 'Search in these namespaces by default:',
 1273+'default' => 'default',
 1274+'files' => 'Files',
12821275
12831276 # User rights
1284 -'userrights-lookup-user' => 'Manage user groups',
1285 -'userrights-user-editname' => 'Enter a username:',
1286 -'editusergroup' => 'Edit User Groups',
1287 -'userrights-editusergroup' => 'Edit user groups',
1288 -'saveusergroups' => 'Save User Groups',
1289 -'userrights-groupsmember' => 'Member of:',
 1277+'userrights-lookup-user' => 'Manage user groups',
 1278+'userrights-user-editname' => 'Enter a username:',
 1279+'editusergroup' => 'Edit User Groups',
 1280+'userrights-editusergroup' => 'Edit user groups',
 1281+'saveusergroups' => 'Save User Groups',
 1282+'userrights-groupsmember' => 'Member of:',
12901283 'userrights-groupsavailable' => 'Available groups:',
1291 -'userrights-groupshelp' => 'Select groups you want the user to be removed from or added to.
 1284+'userrights-groupshelp' => 'Select groups you want the user to be removed from or added to.
12921285 Unselected groups will not be changed. You can deselect a group with CTRL + Left Click',
1293 -'userrights-reason' => 'Reason for change:',
 1286+'userrights-reason' => 'Reason for change:',
12941287
12951288 # Groups
1296 -'group' => 'Group:',
1297 -'group-bot' => 'Bots',
1298 -'group-sysop' => 'Sysops',
1299 -'group-bureaucrat' => 'Bureaucrats',
1300 -'group-all' => '(all)',
 1289+'group' => 'Group:',
 1290+'group-bot' => 'Bots',
 1291+'group-sysop' => 'Sysops',
 1292+'group-bureaucrat' => 'Bureaucrats',
 1293+'group-all' => '(all)',
13011294
13021295 'group-bot-member' => 'Bot',
13031296 'group-sysop-member' => 'Sysop',
13041297 'group-bureaucrat-member' => 'Bureaucrat',
13051298
1306 -'grouppage-bot' => '{{ns:project}}:Bots',
1307 -'grouppage-sysop' => '{{ns:project}}:Administrators',
 1299+'grouppage-bot' => '{{ns:project}}:Bots',
 1300+'grouppage-sysop' => '{{ns:project}}:Administrators',
13081301 'grouppage-bureaucrat' => '{{ns:project}}:Bureaucrats',
13091302
13101303 'oversight' => 'Oversight',
@@ -1318,459 +1311,457 @@
13191312 'rightsnone' => '(none)',
13201313
13211314 # Recent changes
1322 -#
1323 -'nchanges' => '$1 {{PLURAL:$1|change|changes}}',
1324 -'recentchanges' => 'Recent changes',
1325 -'recentchanges-url' => 'Special:Recentchanges',
1326 -'recentchangestext' => 'Track the most recent changes to the wiki on this page.',
1327 -'recentchanges-feed-description' => 'Track the most recent changes to the wiki in this feed.',
1328 -'rcnote' => "Below {{PLURAL:$1|is '''1''' change|are the last '''$1''' changes}} in the last {{PLURAL:$2|day|last '''$2''' days}}, as of $3.",
1329 -'rcnotefrom' => "Below are the changes since <b>$2</b> (up to <b>$1</b> shown).",
1330 -'rclistfrom' => "Show new changes starting from $1",
1331 -'rcshowhideminor' => '$1 minor edits',
1332 -'rcshowhidebots' => '$1 bots',
1333 -'rcshowhideliu' => '$1 logged-in users',
1334 -'rcshowhideanons' => '$1 anonymous users',
1335 -'rcshowhidepatr' => '$1 patrolled edits',
1336 -'rcshowhidemine' => '$1 my edits',
1337 -'rclinks' => "Show last $1 changes in last $2 days<br />$3",
1338 -'diff' => 'diff',
1339 -'hist' => 'hist',
1340 -'hide' => 'Hide',
1341 -'show' => 'Show',
1342 -'minoreditletter' => 'm',
1343 -'newpageletter' => 'N',
1344 -'boteditletter' => 'b',
1345 -'sectionlink' => '→',
1346 -'number_of_watching_users_RCview' => '[$1]',
1347 -'number_of_watching_users_pageview' => '[$1 watching user/s]',
1348 -'rc_categories' => 'Limit to categories (separate with "|")',
1349 -'rc_categories_any' => 'Any',
1350 -'rc-change-size' => '$1',
 1315+'nchanges' => '$1 {{PLURAL:$1|change|changes}}',
 1316+'recentchanges' => 'Recent changes',
 1317+'recentchanges-url' => 'Special:Recentchanges', # don't translate or duplicate this message to other languages
 1318+'recentchangestext' => 'Track the most recent changes to the wiki on this page.',
 1319+'recentchanges-feed-description' => 'Track the most recent changes to the wiki in this feed.',
 1320+'rcnote' => "Below {{PLURAL:$1|is '''1''' change|are the last '''$1''' changes}} in the last {{PLURAL:$2|day|'''$2''' days}}, as of $3.",
 1321+'rcnotefrom' => 'Below are the changes since <b>$2</b> (up to <b>$1</b> shown).',
 1322+'rclistfrom' => 'Show new changes starting from $1',
 1323+'rcshowhideminor' => '$1 minor edits',
 1324+'rcshowhidebots' => '$1 bots',
 1325+'rcshowhideliu' => '$1 logged-in users',
 1326+'rcshowhideanons' => '$1 anonymous users',
 1327+'rcshowhidepatr' => '$1 patrolled edits',
 1328+'rcshowhidemine' => '$1 my edits',
 1329+'rclinks' => 'Show last $1 changes in last $2 days<br />$3',
 1330+'diff' => 'diff',
 1331+'hist' => 'hist',
 1332+'hide' => 'Hide',
 1333+'show' => 'Show',
 1334+'minoreditletter' => 'm',
 1335+'newpageletter' => 'N',
 1336+'boteditletter' => 'b',
 1337+'sectionlink' => '→', # only translate this message to other languages if you have to change it
 1338+'number_of_watching_users_RCview' => '[$1]', # don't translate or duplicate this message to other languages
 1339+'number_of_watching_users_pageview' => '[$1 watching user/s]',
 1340+'rc_categories' => 'Limit to categories (separate with "|")',
 1341+'rc_categories_any' => 'Any',
 1342+'rc-change-size' => '$1', # only translate this message to other languages if you have to change it
13511343
1352 -# Recentchangeslinked
1353 -'recentchangeslinked' => 'Related changes',
1354 -'recentchangeslinked-noresult' => 'No changes on linked pages during the given period.',
1355 -'recentchangeslinked-summary' => "This special page lists the last changes on pages who are linked. Pages on your watchlist are '''bold'''.",
 1344+# Recent changes linked
 1345+'recentchangeslinked' => 'Related changes',
 1346+'recentchangeslinked-noresult' => 'No changes on linked pages during the given period.',
 1347+'recentchangeslinked-summary' => "This special page lists the last changes on pages who are linked. Pages on your watchlist are '''bold'''.",
13561348
13571349 # Upload
1358 -#
1359 -'upload' => 'Upload file',
1360 -'uploadbtn' => 'Upload file',
1361 -'reupload' => 'Re-upload',
1362 -'reuploaddesc' => 'Return to the upload form.',
1363 -'uploadnologin' => 'Not logged in',
1364 -'uploadnologintext' => "You must be [[Special:Userlogin|logged in]]
1365 -to upload files.",
1366 -'upload_directory_read_only' => 'The upload directory ($1) is not writable by the webserver.',
1367 -'uploaderror' => 'Upload error',
1368 -'uploadtext' => "Use the form below to upload files, to view or search previously uploaded images go to the [[Special:Imagelist|list of uploaded files]], uploads and deletions are also logged in the [[Special:Log/upload|upload log]].
 1350+'upload' => 'Upload file',
 1351+'uploadbtn' => 'Upload file',
 1352+'reupload' => 'Re-upload',
 1353+'reuploaddesc' => 'Return to the upload form.',
 1354+'uploadnologin' => 'Not logged in',
 1355+'uploadnologintext' => 'You must be [[Special:Userlogin|logged in]]
 1356+to upload files.',
 1357+'upload_directory_read_only' => 'The upload directory ($1) is not writable by the webserver.',
 1358+'uploaderror' => 'Upload error',
 1359+'uploadtext' => "Use the form below to upload files, to view or search previously uploaded images go to the [[Special:Imagelist|list of uploaded files]], uploads and deletions are also logged in the [[Special:Log/upload|upload log]].
13691360
13701361 To include the image in a page, use a link in the form
13711362 '''<nowiki>[[</nowiki>{{ns:image}}<nowiki>:File.jpg]]</nowiki>''',
13721363 '''<nowiki>[[</nowiki>{{ns:image}}<nowiki>:File.png|alt text]]</nowiki>''' or
13731364 '''<nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki>''' for directly linking to the file.",
1374 -'uploadlog' => 'upload log',
1375 -'uploadlogpage' => 'Upload log',
1376 -'uploadlogpagetext' => 'Below is a list of the most recent file uploads.',
1377 -'filename' => 'Filename',
1378 -'filedesc' => 'Summary',
1379 -'fileuploadsummary' => 'Summary:',
1380 -'filestatus' => 'Copyright status',
1381 -'filesource' => 'Source',
1382 -'copyrightpage' => "Project:Copyrights",
1383 -'copyrightpagename' => "{{SITENAME}} copyright",
1384 -'uploadedfiles' => 'Uploaded files',
1385 -'ignorewarning' => 'Ignore warning and save file anyway.',
1386 -'ignorewarnings' => 'Ignore any warnings',
1387 -'minlength' => 'File names must be at least three letters.',
1388 -'illegalfilename' => 'The filename "$1" contains characters that are not allowed in page titles. Please rename the file and try uploading it again.',
1389 -'badfilename' => 'File name has been changed to "$1".',
 1365+'uploadlog' => 'upload log',
 1366+'uploadlogpage' => 'Upload log',
 1367+'uploadlogpagetext' => 'Below is a list of the most recent file uploads.',
 1368+'filename' => 'Filename',
 1369+'filedesc' => 'Summary',
 1370+'fileuploadsummary' => 'Summary:',
 1371+'filestatus' => 'Copyright status',
 1372+'filesource' => 'Source',
 1373+'uploadedfiles' => 'Uploaded files',
 1374+'ignorewarning' => 'Ignore warning and save file anyway.',
 1375+'ignorewarnings' => 'Ignore any warnings',
 1376+'minlength' => 'File names must be at least three letters.',
 1377+'illegalfilename' => 'The filename "$1" contains characters that are not allowed in page titles. Please rename the file and try uploading it again.',
 1378+'badfilename' => 'File name has been changed to "$1".',
13901379 'filetype-badmime' => 'Files of the MIME type "$1" are not allowed to be uploaded.',
1391 -'filetype-badtype' => "'''\".$1\"''' is an unwanted file type
1392 -: List of allowed file types: $2",
 1380+'filetype-badtype' => "'''\".\$1\"''' is an unwanted file type
 1381+: List of allowed file types: \$2",
13931382 'filetype-missing' => 'The file has no extension (like ".jpg").',
1394 -'large-file' => 'It is recommended that files are no larger than $1; this file is $2.',
1395 -'largefileserver' => 'This file is bigger than the server is configured to allow.',
1396 -'emptyfile' => 'The file you uploaded seems to be empty. This might be due to a typo in the file name. Please check whether you really want to upload this file.',
1397 -'fileexists' => 'A file with this name exists already, please check <strong><tt>$1</tt></strong> if you are not sure if you want to change it.',
 1383+'large-file' => 'It is recommended that files are no larger than $1; this file is $2.',
 1384+'largefileserver' => 'This file is bigger than the server is configured to allow.',
 1385+'emptyfile' => 'The file you uploaded seems to be empty. This might be due to a typo in the file name. Please check whether you really want to upload this file.',
 1386+'fileexists' => 'A file with this name exists already, please check <strong><tt>$1</tt></strong> if you are not sure if you want to change it.',
13981387 'fileexists-extension' => 'A file with a similar name exists:<br />
13991388 Name of the uploading file: <strong><tt>$1</tt></strong><br />
14001389 Name of the existing file: <strong><tt>$2</tt></strong><br />
14011390 Please choose a different name.',
1402 -'fileexists-thumb' => "'''<center>Existing image</center>'''",
1403 -'fileexists-thumbnail-yes' => "The file seems to be an image of reduced size <i>(thumbnail)</i>. Please check the file <strong><tt>$1</tt></strong>.<br />
1404 -If the checked file is the same image of original size it is not necessary to upload an extra thumbnail.",
1405 -'file-thumbnail-no' => "The filename begins with <strong><tt>$1</tt></strong>. It seems to be an image of reduced size <i>(thumbnail)</i>.
1406 -If you have this image in full resolution upload this one, otherwise change the file name please.",
1407 -'fileexists-forbidden' => 'A file with this name exists already; please go back and upload this file under a new name. [[Image:$1|thumb|center|$1]]',
1408 -'fileexists-shared-forbidden' => 'A file with this name exists already in the shared file repository; please go back and upload this file under a new name. [[Image:$1|thumb|center|$1]]',
1409 -'successfulupload' => 'Successful upload',
1410 -'fileuploaded' => "File $1 uploaded successfully.
 1391+'fileexists-thumb' => "'''<center>Existing image</center>'''",
 1392+'fileexists-thumbnail-yes' => 'The file seems to be an image of reduced size <i>(thumbnail)</i>. Please check the file <strong><tt>$1</tt></strong>.<br />
 1393+If the checked file is the same image of original size it is not necessary to upload an extra thumbnail.',
 1394+'file-thumbnail-no' => 'The filename begins with <strong><tt>$1</tt></strong>. It seems to be an image of reduced size <i>(thumbnail)</i>.
 1395+If you have this image in full resolution upload this one, otherwise change the file name please.',
 1396+'fileexists-forbidden' => 'A file with this name exists already; please go back and upload this file under a new name. [[Image:$1|thumb|center|$1]]',
 1397+'fileexists-shared-forbidden' => 'A file with this name exists already in the shared file repository; please go back and upload this file under a new name. [[Image:$1|thumb|center|$1]]',
 1398+'successfulupload' => 'Successful upload',
 1399+'fileuploaded' => 'File $1 uploaded successfully.
14111400 Please follow this link: $2 to the description page and fill
14121401 in information about the file, such as where it came from, when it was
1413 -created and by whom, and anything else you may know about it. If this is an image, you can insert it like this: <tt><nowiki>[[</nowiki>{{ns:image}}<nowiki>:$1|thumb|Description]]</nowiki></tt>",
1414 -'uploadwarning' => 'Upload warning',
1415 -'savefile' => 'Save file',
1416 -'uploadedimage' => "uploaded \"[[$1]]\"",
1417 -'uploaddisabled' => 'Uploads disabled',
1418 -'uploaddisabledtext' => 'File uploads are disabled on this wiki.',
1419 -'uploadscripted' => 'This file contains HTML or script code that may be erroneously be interpreted by a web browser.',
1420 -'uploadcorrupt' => 'The file is corrupt or has an incorrect extension. Please check the file and upload again.',
1421 -'uploadvirus' => 'The file contains a virus! Details: $1',
1422 -'sourcefilename' => 'Source filename',
1423 -'destfilename' => 'Destination filename',
1424 -'watchthisupload' => 'Watch this page',
1425 -'filewasdeleted' => 'A file of this name has been previously uploaded and subsequently deleted. You should check the $1 before proceeding to upload it again.',
 1402+created and by whom, and anything else you may know about it. If this is an image, you can insert it like this: <tt><nowiki>[[</nowiki>{{ns:image}}<nowiki>:$1|thumb|Description]]</nowiki></tt>',
 1403+'uploadwarning' => 'Upload warning',
 1404+'savefile' => 'Save file',
 1405+'uploadedimage' => 'uploaded "[[$1]]"',
 1406+'uploaddisabled' => 'Uploads disabled',
 1407+'uploaddisabledtext' => 'File uploads are disabled on this wiki.',
 1408+'uploadscripted' => 'This file contains HTML or script code that may be erroneously be interpreted by a web browser.',
 1409+'uploadcorrupt' => 'The file is corrupt or has an incorrect extension. Please check the file and upload again.',
 1410+'uploadvirus' => 'The file contains a virus! Details: $1',
 1411+'sourcefilename' => 'Source filename',
 1412+'destfilename' => 'Destination filename',
 1413+'watchthisupload' => 'Watch this page',
 1414+'filewasdeleted' => 'A file of this name has been previously uploaded and subsequently deleted. You should check the $1 before proceeding to upload it again.',
14261415
1427 -'upload-proto-error' => 'Incorrect protocol',
 1416+'upload-proto-error' => 'Incorrect protocol',
14281417 'upload-proto-error-text' => 'Remote upload requires URLs beginning with <code>http://</code> or <code>ftp://</code>.',
1429 -'upload-file-error' => 'Internal error',
1430 -'upload-file-error-text' => 'An internal error occurred when attempting to create a temporary file on the server. Please contact a system administrator.',
1431 -'upload-misc-error' => 'Unknown upload error',
1432 -'upload-misc-error-text' => 'An unknown error occurred during the upload. Please verify that the URL is valid and accessible and try again. If the problem persists, contact a system administrator.',
1433 -# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
1434 -'upload-curl-error6' => "Couldn't reach URL",
1435 -'upload-curl-error6-text' => 'The URL provided could not be reached. Please double-check that the URL is correct and the site is up.',
1436 -'upload-curl-error28' => 'Upload timeout',
 1418+'upload-file-error' => 'Internal error',
 1419+'upload-file-error-text' => 'An internal error occurred when attempting to create a temporary file on the server. Please contact a system administrator.',
 1420+'upload-misc-error' => 'Unknown upload error',
 1421+'upload-misc-error-text' => 'An unknown error occurred during the upload. Please verify that the URL is valid and accessible and try again. If the problem persists, contact a system administrator.',
 1422+
 1423+# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
 1424+'upload-curl-error6' => "Couldn't reach URL",
 1425+'upload-curl-error6-text' => 'The URL provided could not be reached. Please double-check that the URL is correct and the site is up.',
 1426+'upload-curl-error28' => 'Upload timeout',
14371427 'upload-curl-error28-text' => 'The site took too long to respond. Please check the site is up, wait a short while and try again. You may want to try at a less busy time.',
14381428
1439 -'license' => 'Licensing',
1440 -'nolicense' => 'None selected',
1441 -'licenses' => '-', # Don't duplicate this in translations
1442 -'upload_source_url' => ' (a valid, publicly accessible URL)',
 1429+'license' => 'Licensing',
 1430+'nolicense' => 'None selected',
 1431+'licenses' => '-', # don't translate or duplicate this message to other languages
 1432+'upload_source_url' => ' (a valid, publicly accessible URL)',
14431433 'upload_source_file' => ' (a file on your computer)',
14441434
14451435 # Image list
1446 -#
1447 -'imagelist' => 'File list',
1448 -'imagelist-summary' => '',
1449 -'imagelisttext' => "Below is a list of '''$1''' {{PLURAL:$1|file|files}} sorted $2.",
1450 -'imagelistforuser' => "This shows only images uploaded by $1.",
1451 -'getimagelist' => 'fetching file list',
1452 -'ilsubmit' => 'Search',
1453 -'showlast' => 'Show last $1 files sorted $2.',
1454 -'byname' => 'by name',
1455 -'bydate' => 'by date',
1456 -'bysize' => 'by size',
1457 -'imgdelete' => 'del',
1458 -'imgdesc' => 'desc',
1459 -'imgfile' => 'file',
1460 -'imglegend' => 'Legend: (desc) = show/edit file description.',
1461 -'imghistory' => 'File history',
1462 -'revertimg' => 'rev',
1463 -'deleteimg' => 'del',
1464 -'deleteimgcompletely' => 'Delete all revisions of this file',
1465 -'imghistlegend' => 'Legend: (cur) = this is the current file, (rev) = revert to this old version.
 1436+'imagelist' => 'File list',
 1437+'imagelist-summary' => '', # only translate this message to other languages if you have to change it
 1438+'imagelisttext' => "Below is a list of '''$1''' {{PLURAL:$1|file|files}} sorted $2.",
 1439+'imagelistforuser' => 'This shows only images uploaded by $1.',
 1440+'getimagelist' => 'fetching file list',
 1441+'ilsubmit' => 'Search',
 1442+'showlast' => 'Show last $1 files sorted $2.',
 1443+'byname' => 'by name',
 1444+'bydate' => 'by date',
 1445+'bysize' => 'by size',
 1446+'imgdelete' => 'del',
 1447+'imgdesc' => 'desc',
 1448+'imgfile' => 'file',
 1449+'imglegend' => 'Legend: (desc) = show/edit file description.',
 1450+'imghistory' => 'File history',
 1451+'revertimg' => 'rev',
 1452+'deleteimg' => 'del',
 1453+'deleteimgcompletely' => 'Delete all revisions of this file',
 1454+'imghistlegend' => 'Legend: (cur) = this is the current file, (rev) = revert to this old version.
 1455+
14661456 <br /><i>Click on date to see the file uploaded on that date</i>.',
1467 -'imagelinks' => 'Links',
1468 -'linkstoimage' => 'The following pages link to this file:',
1469 -'nolinkstoimage' => 'There are no pages that link to this file.',
1470 -'sharedupload' => 'This file is a shared upload and may be used by other projects.',
1471 -'shareduploadwiki' => 'Please see the $1 for further information.',
 1457+'imagelinks' => 'Links',
 1458+'linkstoimage' => 'The following pages link to this file:',
 1459+'nolinkstoimage' => 'There are no pages that link to this file.',
 1460+'sharedupload' => 'This file is a shared upload and may be used by other projects.',
 1461+'shareduploadwiki' => 'Please see the $1 for further information.',
14721462 'shareduploadwiki-linktext' => 'file description page',
1473 -'shareddescriptionfollows' => '-',
1474 -'noimage' => 'No file by this name exists, you can $1.',
1475 -'noimage-linktext' => 'upload it',
 1463+'shareddescriptionfollows' => '-', # don't translate or duplicate this message to other languages
 1464+'noimage' => 'No file by this name exists, you can $1.',
 1465+'noimage-linktext' => 'upload it',
14761466 'uploadnewversion-linktext' => 'Upload a new version of this file',
1477 -'imagelist_date' => 'Date',
1478 -'imagelist_name' => 'Name',
1479 -'imagelist_user' => 'User',
1480 -'imagelist_size' => 'Size',
1481 -'imagelist_description' => 'Description',
1482 -'imagelist_search_for' => 'Search for image name:',
 1467+'imagelist_date' => 'Date',
 1468+'imagelist_name' => 'Name',
 1469+'imagelist_user' => 'User',
 1470+'imagelist_size' => 'Size',
 1471+'imagelist_description' => 'Description',
 1472+'imagelist_search_for' => 'Search for image name:',
14831473
1484 -# Mime search
1485 -#
1486 -'mimesearch' => 'MIME search',
 1474+# MIME search
 1475+'mimesearch' => 'MIME search',
14871476 'mimesearch-summary' => 'This page enables the filtering of files for its MIME-type. Input: contenttype/subtype, e.g. <tt>image/jpeg</tt>.',
1488 -'mimetype' => 'MIME type:',
1489 -'download' => 'download',
 1477+'mimetype' => 'MIME type:',
 1478+'download' => 'download',
14901479
1491 -# Unwatchedpages
1492 -#
1493 -'unwatchedpages' => 'Unwatched pages',
1494 -'unwatchedpages-summary' => '',
 1480+# Unwatched pages
 1481+'unwatchedpages' => 'Unwatched pages',
 1482+'unwatchedpages-summary' => '', # only translate this message to other languages if you have to change it
14951483
14961484 # List redirects
1497 -'listredirects' => 'List redirects',
1498 -'listredirects-summary' => '',
 1485+'listredirects' => 'List redirects',
 1486+'listredirects-summary' => '', # only translate this message to other languages if you have to change it
14991487
15001488 # Unused templates
1501 -'unusedtemplates' => 'Unused templates',
1502 -'unusedtemplates-summary' => '',
1503 -'unusedtemplatestext' => 'This page lists all pages in the template namespace which are not included in another page. Remember to check for other links to the templates before deleting them.',
1504 -'unusedtemplateswlh' => 'other links',
 1489+'unusedtemplates' => 'Unused templates',
 1490+'unusedtemplates-summary' => '', # only translate this message to other languages if you have to change it
 1491+'unusedtemplatestext' => 'This page lists all pages in the template namespace which are not included in another page. Remember to check for other links to the templates before deleting them.',
 1492+'unusedtemplateswlh' => 'other links',
15051493
15061494 # Random redirect
1507 -'randomredirect' => 'Random redirect',
 1495+'randomredirect' => 'Random redirect',
15081496 'randomredirect-nopages' => 'There are no redirects in this namespace.',
15091497
15101498 # Statistics
1511 -#
1512 -'statistics' => 'Statistics',
1513 -'sitestats' => '{{SITENAME}} statistics',
1514 -'userstats' => 'User statistics',
1515 -'sitestatstext' => "There {{PLURAL:$1|is '''1''' page|are '''$1''' total pages}} in the database.
 1499+'statistics' => 'Statistics',
 1500+'sitestats' => '{{SITENAME}} statistics',
 1501+'userstats' => 'User statistics',
 1502+'sitestatstext' => "There {{PLURAL:\$1|is '''1''' page|are '''\$1''' total pages}} in the database.
15161503 This includes \"talk\" pages, pages about {{SITENAME}}, minimal \"stub\"
15171504 pages, redirects, and others that probably don't qualify as content pages.
1518 -Excluding those, there {{PLURAL:$2|is '''1''' page that is a|are '''$2''' pages that are}} probably legitimate
1519 -content {{PLURAL:$2|page|pages}}.
 1505+Excluding those, there {{PLURAL:\$2|is '''1''' page that is a|are '''\$2''' pages that are}} probably legitimate
 1506+content {{PLURAL:\$2|page|pages}}.
15201507
1521 -'''$8''' {{PLURAL:$8|file|files}} have been uploaded.
 1508+'''\$8''' {{PLURAL:\$8|file|files}} have been uploaded.
15221509
1523 -There have been a total of '''$3''' {{PLURAL:$3|page view|page views}}, and '''$4''' {{PLURAL:$4|page edit|page edits}}
 1510+There have been a total of '''\$3''' {{PLURAL:\$3|page view|page views}}, and '''\$4''' {{PLURAL:\$4|page edit|page edits}}
15241511 since {{SITENAME}} was setup.
1525 -That comes to '''$5''' average edits per page, and '''$6''' views per edit.
 1512+That comes to '''\$5''' average edits per page, and '''\$6''' views per edit.
15261513
1527 -The [http://meta.wikimedia.org/wiki/Help:Job_queue job queue] length is '''$7'''.",
1528 -'userstatstext' => "There {{PLURAL:$1|is '''1''' registered user|are '''$1''' registered users}}, of which
 1514+The [http://meta.wikimedia.org/wiki/Help:Job_queue job queue] length is '''\$7'''.",
 1515+'userstatstext' => "There {{PLURAL:$1|is '''1''' registered user|are '''$1''' registered users}}, of which
15291516 '''$2''' (or '''$4%''') {{PLURAL:$2|has|have}} $5 rights.",
15301517 'statistics-mostpopular' => 'Most viewed pages',
1531 -'statistics-footer' => '',
 1518+'statistics-footer' => '', # don't translate or duplicate this message to other languages
15321519
1533 -'disambiguations' => 'Disambiguation pages',
1534 -'disambiguations-summary' => '',
1535 -'disambiguationspage' => 'Template:disambig',
1536 -'disambiguations-text' => "The following pages link to a '''disambiguation page'''. They should link to the appropriate topic instead.<br />A page is treated as disambiguation page if it uses a template which is linked from [[MediaWiki:disambiguationspage]]",
 1520+'disambiguations' => 'Disambiguation pages',
 1521+'disambiguations-summary' => '', # only translate this message to other languages if you have to change it
 1522+'disambiguationspage' => 'Template:disambig',
 1523+'disambiguations-text' => "The following pages link to a '''disambiguation page'''. They should link to the appropriate topic instead.<br />A page is treated as disambiguation page if it uses a template which is linked from [[MediaWiki:disambiguationspage]]",
15371524
1538 -'doubleredirects' => 'Double redirects',
1539 -'doubleredirects-summary' => '',
1540 -'doubleredirectstext' => "Each row contains links to the first and second redirect, as well as the first line of the second redirect text, usually giving the \"real\" target page, which the first redirect should point to.",
 1525+'doubleredirects' => 'Double redirects',
 1526+'doubleredirects-summary' => '', # only translate this message to other languages if you have to change it
 1527+'doubleredirectstext' => 'Each row contains links to the first and second redirect, as well as the first line of the second redirect text, usually giving the "real" target page, which the first redirect should point to.',
15411528
1542 -'brokenredirects' => 'Broken redirects',
1543 -'brokenredirects-summary' => '',
1544 -'brokenredirectstext' => 'The following redirects link to non-existent pages:',
1545 -'brokenredirects-edit' => '(edit)',
1546 -'brokenredirects-delete' => '(delete)',
 1529+'brokenredirects' => 'Broken redirects',
 1530+'brokenredirects-summary' => '', # only translate this message to other languages if you have to change it
 1531+'brokenredirectstext' => 'The following redirects link to non-existent pages:',
 1532+'brokenredirects-edit' => '(edit)',
 1533+'brokenredirects-delete' => '(delete)',
15471534
1548 -'withoutinterwiki' => 'Pages without language links',
1549 -'withoutinterwiki-header' => 'The following pages do not link to other language versions:',
1550 -'withoutinterwiki-summary' => '',
 1535+'withoutinterwiki' => 'Pages without language links',
 1536+'withoutinterwiki-header' => 'The following pages do not link to other language versions:',
 1537+'withoutinterwiki-summary' => '', # only translate this message to other languages if you have to change it
15511538
1552 -'fewestrevisions' => 'Articles with the fewest revisions',
1553 -'fewestrevisions-summary' => '',
 1539+'fewestrevisions' => 'Articles with the fewest revisions',
 1540+'fewestrevisions-summary' => '', # only translate this message to other languages if you have to change it
15541541
15551542 # Miscellaneous special pages
1556 -#
1557 -'nbytes' => '$1 {{PLURAL:$1|byte|bytes}}',
1558 -'ncategories' => '$1 {{PLURAL:$1|category|categories}}',
1559 -'nlinks' => '$1 {{PLURAL:$1|link|links}}',
1560 -'nmembers' => '$1 {{PLURAL:$1|member|members}}',
1561 -'nrevisions' => '$1 {{PLURAL:$1|revision|revisions}}',
1562 -'nviews' => '$1 {{PLURAL:$1|view|views}}',
1563 -'specialpage-empty' => 'This page is empty.',
1564 -'lonelypages' => 'Orphaned pages',
1565 -'lonelypages-summary' => '',
1566 -'lonelypagestext' => 'The following pages are not linked from other pages in this wiki.',
1567 -'uncategorizedpages' => 'Uncategorized pages',
1568 -'uncategorizedpages-summary' => '',
1569 -'uncategorizedcategories' => 'Uncategorized categories',
1570 -'uncategorizedcategories-summary' => '',
1571 -'uncategorizedimages' => 'Uncategorized images',
1572 -'uncategorizedimages-summary' => '',
1573 -'unusedcategories' => 'Unused categories',
1574 -'unusedimages' => 'Unused files',
1575 -'popularpages' => 'Popular pages',
1576 -'popularpages-summary' => '',
1577 -'wantedcategories' => 'Wanted categories',
1578 -'wantedcategories-summary' => '',
1579 -'wantedpages' => 'Wanted pages',
1580 -'wantedpages-summary' => '',
1581 -'mostlinked' => 'Most linked to pages',
1582 -'mostlinked-summary' => '',
1583 -'mostlinkedcategories' => 'Most linked to categories',
1584 -'mostlinkedcategories-summary' => '',
1585 -'mostcategories' => 'Articles with the most categories',
1586 -'mostcategories-summary' => '',
1587 -'mostimages' => 'Most linked to images',
1588 -'mostimages-summary' => '',
1589 -'mostrevisions' => 'Articles with the most revisions',
1590 -'mostrevisions-summary' => '',
1591 -'allpages' => 'All pages',
1592 -'allpages-summary' => '',
1593 -'prefixindex' => 'Prefix index',
1594 -'prefixindex-summary' => '',
1595 -'randompage' => 'Random page',
1596 -'randompage-nopages' => 'There are no pages in this namespace.',
1597 -'randompage-url'=> 'Special:Random',
1598 -'shortpages' => 'Short pages',
1599 -'shortpages-summary' => '',
1600 -'longpages' => 'Long pages',
1601 -'longpages-summary' => '',
1602 -'deadendpages' => 'Dead-end pages',
1603 -'deadendpages-summary' => '',
1604 -'deadendpagestext' => 'The following pages do not link to other pages in this wiki.',
1605 -'protectedpages' => 'Protected pages',
1606 -'protectedpages-summary' => '',
1607 -'protectedpagestext' => 'The following pages are protected from moving or editing',
1608 -'protectedpagesempty' => 'No pages are currently protected with these parameters.',
1609 -'listusers' => 'User list',
1610 -'listusers-summary' => '',
1611 -'specialpages' => 'Special pages',
1612 -'specialpages-summary' => '',
1613 -'spheading' => 'Special pages for all users',
1614 -'restrictedpheading' => 'Restricted special pages',
1615 -'rclsub' => "(to pages linked from \"$1\")",
1616 -'newpages' => 'New pages',
1617 -'newpages-summary' => '',
1618 -'newpages-username' => 'Username:',
1619 -'ancientpages' => 'Oldest pages',
1620 -'ancientpages-summary' => '',
1621 -'intl' => 'Interlanguage links',
1622 -'move' => 'Move',
1623 -'movethispage' => 'Move this page',
1624 -'unusedimagestext' => '<p>Please note that other web sites may link to an image with
 1543+'nbytes' => '$1 {{PLURAL:$1|byte|bytes}}',
 1544+'ncategories' => '$1 {{PLURAL:$1|category|categories}}',
 1545+'nlinks' => '$1 {{PLURAL:$1|link|links}}',
 1546+'nmembers' => '$1 {{PLURAL:$1|member|members}}',
 1547+'nrevisions' => '$1 {{PLURAL:$1|revision|revisions}}',
 1548+'nviews' => '$1 {{PLURAL:$1|view|views}}',
 1549+'specialpage-empty' => 'There are no results for this report.',
 1550+'lonelypages' => 'Orphaned pages',
 1551+'lonelypages-summary' => '', # only translate this message to other languages if you have to change it
 1552+'lonelypagestext' => 'The following pages are not linked from other pages in this wiki.',
 1553+'uncategorizedpages' => 'Uncategorized pages',
 1554+'uncategorizedpages-summary' => '', # only translate this message to other languages if you have to change it
 1555+'uncategorizedcategories' => 'Uncategorized categories',
 1556+'uncategorizedcategories-summary' => '', # only translate this message to other languages if you have to change it
 1557+'uncategorizedimages' => 'Uncategorized images',
 1558+'uncategorizedimages-summary' => '', # only translate this message to other languages if you have to change it
 1559+'uncategorizedtemplates' => 'Uncategorized templates',
 1560+'uncategorizedtemplates-summary' => '',
 1561+'unusedcategories' => 'Unused categories',
 1562+'unusedimages' => 'Unused files',
 1563+'popularpages' => 'Popular pages',
 1564+'popularpages-summary' => '', # only translate this message to other languages if you have to change it
 1565+'wantedcategories' => 'Wanted categories',
 1566+'wantedcategories-summary' => '', # only translate this message to other languages if you have to change it
 1567+'wantedpages' => 'Wanted pages',
 1568+'wantedpages-summary' => '', # only translate this message to other languages if you have to change it
 1569+'mostlinked' => 'Most linked to pages',
 1570+'mostlinked-summary' => '', # only translate this message to other languages if you have to change it
 1571+'mostlinkedcategories' => 'Most linked to categories',
 1572+'mostlinkedcategories-summary' => '', # only translate this message to other languages if you have to change it
 1573+'mostlinkedtemplates' => 'Most linked-to templates',
 1574+'mostlinkedtemplates-summary' => '', # only translate this message to other languages if you have to change it
 1575+'mostcategories' => 'Articles with the most categories',
 1576+'mostcategories-summary' => '', # only translate this message to other languages if you have to change it
 1577+'mostimages' => 'Most linked to images',
 1578+'mostimages-summary' => '', # only translate this message to other languages if you have to change it
 1579+'mostrevisions' => 'Articles with the most revisions',
 1580+'mostrevisions-summary' => '', # only translate this message to other languages if you have to change it
 1581+'allpages' => 'All pages',
 1582+'allpages-summary' => '', # only translate this message to other languages if you have to change it
 1583+'prefixindex' => 'Prefix index',
 1584+'prefixindex-summary' => '', # only translate this message to other languages if you have to change it
 1585+'randompage' => 'Random page',
 1586+'randompage-nopages' => 'There are no pages in this namespace.',
 1587+'randompage-url' => 'Special:Random', # don't translate or duplicate this message to other languages
 1588+'shortpages' => 'Short pages',
 1589+'shortpages-summary' => '', # only translate this message to other languages if you have to change it
 1590+'longpages' => 'Long pages',
 1591+'longpages-summary' => '', # only translate this message to other languages if you have to change it
 1592+'deadendpages' => 'Dead-end pages',
 1593+'deadendpages-summary' => '', # only translate this message to other languages if you have to change it
 1594+'deadendpagestext' => 'The following pages do not link to other pages in this wiki.',
 1595+'protectedpages' => 'Protected pages',
 1596+'protectedpages-summary' => '', # only translate this message to other languages if you have to change it
 1597+'protectedpagestext' => 'The following pages are protected from moving or editing',
 1598+'protectedpagesempty' => 'No pages are currently protected with these parameters.',
 1599+'listusers' => 'User list',
 1600+'listusers-summary' => '', # only translate this message to other languages if you have to change it
 1601+'specialpages' => 'Special pages',
 1602+'specialpages-summary' => '', # only translate this message to other languages if you have to change it
 1603+'spheading' => 'Special pages for all users',
 1604+'restrictedpheading' => 'Restricted special pages',
 1605+'restrictedlheading' => 'Restricted logs',
 1606+'rclsub' => '(to pages linked from "$1")',
 1607+'newpages' => 'New pages',
 1608+'newpages-summary' => '', # only translate this message to other languages if you have to change it
 1609+'newpages-username' => 'Username:',
 1610+'ancientpages' => 'Oldest pages',
 1611+'ancientpages-summary' => '', # only translate this message to other languages if you have to change it
 1612+'intl' => 'Interlanguage links',
 1613+'move' => 'Move',
 1614+'movethispage' => 'Move this page',
 1615+'unusedimagestext' => '<p>Please note that other web sites may link to an image with
16251616 a direct URL, and so may still be listed here despite being
16261617 in active use.</p>',
1627 -'unusedcategoriestext' => 'The following category pages exist although no other article or category make use of them.',
 1618+'unusedcategoriestext' => 'The following category pages exist although no other article or category make use of them.',
16281619
16291620 # Book sources
1630 -'booksources' => 'Book sources',
1631 -'booksources-summary' => '',
 1621+'booksources' => 'Book sources',
 1622+'booksources-summary' => '', # only translate this message to other languages if you have to change it
16321623 'booksources-search-legend' => 'Search for book sources',
1633 -'booksources-isbn' => 'ISBN:',
1634 -'booksources-go' => 'Go',
1635 -'booksources-text' => 'Below is a list of links to other sites that sell new and used books, and may also have
 1624+'booksources-isbn' => 'ISBN:',
 1625+'booksources-go' => 'Go',
 1626+'booksources-text' => 'Below is a list of links to other sites that sell new and used books, and may also have
16361627 further information about books you are looking for:',
16371628
16381629 'categoriespagetext' => 'The following categories exist in the wiki.',
1639 -'data' => 'Data',
1640 -'userrights' => 'User rights management',
1641 -'userrights-summary' => '',
1642 -'groups' => 'User groups',
 1630+'data' => 'Data',
 1631+'userrights' => 'User rights management',
 1632+'userrights-summary' => '', # only translate this message to other languages if you have to change it
 1633+'groups' => 'User groups',
 1634+'isbn' => 'ISBN',
 1635+'rfcurl' => 'http://tools.ietf.org/html/rfc$1', # don't translate or duplicate this message to other languages
 1636+'pubmedurl' => 'http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=pubmed&dopt=Abstract&list_uids=$1', # don't translate or duplicate this message to other languages
 1637+'alphaindexline' => '$1 to $2',
 1638+'version' => 'Version',
16431639
1644 -'isbn' => 'ISBN',
1645 -'rfcurl' => 'http://tools.ietf.org/html/rfc$1',
1646 -'pubmedurl' => 'http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=pubmed&dopt=Abstract&list_uids=$1',
1647 -'alphaindexline' => "$1 to $2",
1648 -'version' => 'Version',
1649 -
1650 -# Special:Logs
 1640+# Special:Log
16511641 'specialloguserlabel' => 'User:',
16521642 'speciallogtitlelabel' => 'Title:',
16531643 'log' => 'Logs',
1654 -'log-search-legend' => 'Search for logs',
1655 -'log-search-submit' => 'Go',
 1644+'all-logs-page' => 'All public logs',
 1645+'log-search-legend' => 'Search for logs',
 1646+'log-search-submit' => 'Go',
16561647 'alllogstext' => 'Combined display of all available public logs of {{SITENAME}}.
16571648 You can narrow down the view by selecting a log type, the user name, or the affected page.',
16581649 'logempty' => 'No matching items in log.',
1659 -'log-title-wildcard' => 'Search titles starting with this text',
 1650+'log-title-wildcard' => 'Search titles starting with this text',
16601651
16611652 # Special:Allpages
16621653 'nextpage' => 'Next page ($1)',
16631654 'prevpage' => 'Previous page ($1)',
1664 -'allpagesfrom' => 'Display pages starting at:',
1665 -'allarticles' => 'All articles',
1666 -'allinnamespace' => 'All pages ($1 namespace)',
1667 -'allnotinnamespace' => 'All pages (not in $1 namespace)',
1668 -'allpagesprev' => 'Previous',
1669 -'allpagesnext' => 'Next',
1670 -'allpagessubmit' => 'Go',
1671 -'allpagesprefix' => 'Display pages with prefix:',
1672 -'allpagesbadtitle' => 'The given page title was invalid or had an inter-language or inter-wiki prefix. It may contain one or more characters which cannot be used in titles.',
 1655+'allpagesfrom' => 'Display pages starting at:',
 1656+'allarticles' => 'All articles',
 1657+'allinnamespace' => 'All pages ($1 namespace)',
 1658+'allnotinnamespace' => 'All pages (not in $1 namespace)',
 1659+'allpagesprev' => 'Previous',
 1660+'allpagesnext' => 'Next',
 1661+'allpagessubmit' => 'Go',
 1662+'allpagesprefix' => 'Display pages with prefix:',
 1663+'allpagesbadtitle' => 'The given page title was invalid or had an inter-language or inter-wiki prefix. It may contain one or more characters which cannot be used in titles.',
16731664
16741665 # Special:Listusers
16751666 'listusersfrom' => 'Display users starting at:',
16761667 'listusers-submit' => 'Show',
16771668 'listusers-noresult' => 'No user found.',
16781669
1679 -# Email this user
1680 -#
1681 -'mailnologin' => 'No send address',
1682 -'mailnologintext' => "You must be [[Special:Userlogin|logged in]]
 1670+# E-mail user
 1671+'mailnologin' => 'No send address',
 1672+'mailnologintext' => 'You must be [[Special:Userlogin|logged in]]
16831673 and have a valid e-mail address in your [[Special:Preferences|preferences]]
1684 -to send e-mail to other users.",
1685 -'emailuser' => 'E-mail this user',
1686 -'emailpage' => 'E-mail user',
1687 -'emailpagetext' => 'If this user has entered a valid e-mail address in
 1674+to send e-mail to other users.',
 1675+'emailuser' => 'E-mail this user',
 1676+'emailpage' => 'E-mail user',
 1677+'emailpagetext' => 'If this user has entered a valid e-mail address in
16881678 his or her user preferences, the form below will send a single message.
16891679 The e-mail address you entered in your user preferences will appear
16901680 as the "From" address of the mail, so the recipient will be able
16911681 to reply.',
16921682 'usermailererror' => 'Mail object returned error:',
1693 -'defemailsubject' => "{{SITENAME}} e-mail",
1694 -'noemailtitle' => 'No e-mail address',
1695 -'noemailtext' => 'This user has not specified a valid e-mail address,
 1683+'defemailsubject' => '{{SITENAME}} e-mail',
 1684+'noemailtitle' => 'No e-mail address',
 1685+'noemailtext' => 'This user has not specified a valid e-mail address,
16961686 or has chosen not to receive e-mail from other users.',
1697 -'emailfrom' => 'From',
1698 -'emailto' => 'To',
1699 -'emailsubject' => 'Subject',
1700 -'emailmessage' => 'Message',
1701 -'emailsend' => 'Send',
1702 -'emailccme' => 'E-mail me a copy of my message.',
1703 -'emailccsubject'=> 'Copy of your message to $1: $2',
1704 -'emailsent' => 'E-mail sent',
1705 -'emailsenttext' => 'Your e-mail message has been sent.',
 1687+'emailfrom' => 'From',
 1688+'emailto' => 'To',
 1689+'emailsubject' => 'Subject',
 1690+'emailmessage' => 'Message',
 1691+'emailsend' => 'Send',
 1692+'emailccme' => 'E-mail me a copy of my message.',
 1693+'emailccsubject' => 'Copy of your message to $1: $2',
 1694+'emailsent' => 'E-mail sent',
 1695+'emailsenttext' => 'Your e-mail message has been sent.',
17061696
17071697 # Watchlist
1708 -'watchlist' => 'My watchlist',
1709 -'mywatchlist' => 'My watchlist',
1710 -'watchlistfor' => "(for '''$1''')",
1711 -'nowatchlist' => 'You have no items on your watchlist.',
1712 -'watchlistanontext' => 'Please $1 to view or edit items on your watchlist.',
1713 -'watchlistcount' => "'''You have {{PLURAL:$1|$1 item|$1 items}} on your watchlist, including talk pages.'''",
1714 -'clearwatchlist' => 'Clear watchlist',
1715 -'watchlistcleartext' => 'Are you sure you wish to remove them?',
 1698+'watchlist' => 'My watchlist',
 1699+'mywatchlist' => 'My watchlist',
 1700+'watchlistfor' => "(for '''$1''')",
 1701+'nowatchlist' => 'You have no items on your watchlist.',
 1702+'watchlistanontext' => 'Please $1 to view or edit items on your watchlist.',
 1703+'watchlistcount' => "'''You have {{PLURAL:$1|$1 item|$1 items}} on your watchlist, including talk pages.'''",
 1704+'clearwatchlist' => 'Clear watchlist',
 1705+'watchlistcleartext' => 'Are you sure you wish to remove them?',
17161706 'watchlistclearbutton' => 'Clear watchlist',
1717 -'watchlistcleardone' => 'Your watchlist has been cleared. {{PLURAL:$1|$1 item was|$1 items were}} removed.',
1718 -'watchnologin' => 'Not logged in',
1719 -'watchnologintext' => 'You must be [[Special:Userlogin|logged in]] to modify your watchlist.',
1720 -'addedwatch' => 'Added to watchlist',
1721 -'addedwatchtext' => "The page \"[[:$1]]\" has been added to your [[Special:Watchlist|watchlist]].
 1707+'watchlistcleardone' => 'Your watchlist has been cleared. {{PLURAL:$1|$1 item was|$1 items were}} removed.',
 1708+'watchnologin' => 'Not logged in',
 1709+'watchnologintext' => 'You must be [[Special:Userlogin|logged in]] to modify your watchlist.',
 1710+'addedwatch' => 'Added to watchlist',
 1711+'addedwatchtext' => "The page \"[[:\$1]]\" has been added to your [[Special:Watchlist|watchlist]].
17221712 Future changes to this page and its associated Talk page will be listed there,
17231713 and the page will appear '''bolded''' in the [[Special:Recentchanges|list of recent changes]] to
17241714 make it easier to pick out.
17251715
17261716 If you want to remove the page from your watchlist later, click \"Unwatch\" in the sidebar.",
1727 -'removedwatch' => 'Removed from watchlist',
1728 -'removedwatchtext' => "The page \"[[:$1]]\" has been removed from your watchlist.",
1729 -'watch' => 'Watch',
1730 -'watchthispage' => 'Watch this page',
1731 -'unwatch' => 'Unwatch',
1732 -'unwatchthispage' => 'Stop watching',
1733 -'notanarticle' => 'Not a content page',
1734 -'watchnochange' => 'None of your watched items was edited in the time period displayed.',
1735 -'watchdetails' => '* {{PLURAL:$1|$1 page|$1 pages}} watched not counting talk pages
 1717+'removedwatch' => 'Removed from watchlist',
 1718+'removedwatchtext' => 'The page "[[:$1]]" has been removed from your watchlist.',
 1719+'watch' => 'Watch',
 1720+'watchthispage' => 'Watch this page',
 1721+'unwatch' => 'Unwatch',
 1722+'unwatchthispage' => 'Stop watching',
 1723+'notanarticle' => 'Not a content page',
 1724+'watchnochange' => 'None of your watched items was edited in the time period displayed.',
 1725+'watchdetails' => '* {{PLURAL:$1|$1 page|$1 pages}} watched not counting talk pages
17361726 * [[Special:Watchlist/edit|Show and edit complete watchlist]]
17371727 * [[Special:Watchlist/clear|Remove all pages]]',
1738 -'wlheader-enotif' => "* E-mail notification is enabled.",
1739 -'wlheader-showupdated' => "* Pages which have been changed since you last visited them are shown in '''bold'''",
1740 -'watchmethod-recent'=> 'checking recent edits for watched pages',
1741 -'watchmethod-list' => 'checking watched pages for recent edits',
1742 -'removechecked' => 'Remove checked items from watchlist',
1743 -'watchlistcontains' => "Your watchlist contains $1 {{PLURAL:$1|page|pages}}.",
1744 -'watcheditlist' => 'Here\'s an alphabetical list of your
1745 -watched content pages. Check the boxes of pages you want to remove from your watchlist and click the \'remove checked\' button
1746 -at the bottom of the screen (deleting a content page also deletes the accompanying talk page and vice versa).',
1747 -'removingchecked' => 'Removing requested items from watchlist...',
1748 -'couldntremove' => "Couldn't remove item '$1'...",
1749 -'iteminvalidname' => "Problem with item '$1', invalid name...",
1750 -'wlnote' => "Below {{PLURAL:$1|is the last change|are the last '''$1''' changes}} in the last {{PLURAL:$2|hour|'''$2''' hours}}.",
1751 -'wlshowlast' => 'Show last $1 hours $2 days $3',
1752 -'wlsaved' => 'This is a saved version of your watchlist.',
1753 -'watchlist-show-bots' => 'Show bot edits',
1754 -'watchlist-hide-bots' => 'Hide bot edits',
1755 -'watchlist-show-own' => 'Show my edits',
1756 -'watchlist-hide-own' => 'Hide my edits',
 1728+'wlheader-enotif' => '* E-mail notification is enabled.',
 1729+'wlheader-showupdated' => "* Pages which have been changed since you last visited them are shown in '''bold'''",
 1730+'watchmethod-recent' => 'checking recent edits for watched pages',
 1731+'watchmethod-list' => 'checking watched pages for recent edits',
 1732+'removechecked' => 'Remove checked items from watchlist',
 1733+'watchlistcontains' => 'Your watchlist contains $1 {{PLURAL:$1|page|pages}}.',
 1734+'watcheditlist' => "Here's an alphabetical list of your
 1735+watched content pages. Check the boxes of pages you want to remove from your watchlist and click the 'remove checked' button
 1736+at the bottom of the screen (deleting a content page also deletes the accompanying talk page and vice versa).",
 1737+'removingchecked' => 'Removing requested items from watchlist...',
 1738+'couldntremove' => "Couldn't remove item '$1'...",
 1739+'iteminvalidname' => "Problem with item '$1', invalid name...",
 1740+'wlnote' => "Below {{PLURAL:$1|is the last change|are the last '''$1''' changes}} in the last {{PLURAL:$2|hour|'''$2''' hours}}.",
 1741+'wlshowlast' => 'Show last $1 hours $2 days $3',
 1742+'wlsaved' => 'This is a saved version of your watchlist.',
 1743+'watchlist-show-bots' => 'Show bot edits',
 1744+'watchlist-hide-bots' => 'Hide bot edits',
 1745+'watchlist-show-own' => 'Show my edits',
 1746+'watchlist-hide-own' => 'Hide my edits',
17571747 'watchlist-show-minor' => 'Show minor edits',
17581748 'watchlist-hide-minor' => 'Hide minor edits',
1759 -'wldone' => 'Done.',
 1749+'wldone' => 'Done.',
 1750+
17601751 # Displayed when you click the "watch" button and it's in the process of watching
1761 -'watching' => 'Watching...',
 1752+'watching' => 'Watching...',
17621753 'unwatching' => 'Unwatching...',
17631754
1764 -'enotif_mailer' => '{{SITENAME}} Notification Mailer',
1765 -'enotif_reset' => 'Mark all pages visited',
1766 -'enotif_newpagetext'=> 'This is a new page.',
1767 -'enotif_impersonal_salutation' => '{{SITENAME}} user',
1768 -'changed' => 'changed',
1769 -'created' => 'created',
1770 -'enotif_subject' => '{{SITENAME}} page $PAGETITLE has been $CHANGEDORCREATED by $PAGEEDITOR',
1771 -'enotif_lastvisited' => 'See $1 for all changes since your last visit.',
1772 -'enotif_lastdiff' => 'See $1 to view this change.',
1773 -'enotif_anon_editor' => 'anonymous user $1',
1774 -'enotif_body' => 'Dear $WATCHINGUSERNAME,
 1755+'enotif_mailer' => '{{SITENAME}} Notification Mailer',
 1756+'enotif_reset' => 'Mark all pages visited',
 1757+'enotif_newpagetext' => 'This is a new page.',
 1758+'enotif_impersonal_salutation' => '{{SITENAME}} user',
 1759+'changed' => 'changed',
 1760+'created' => 'created',
 1761+'enotif_subject' => '{{SITENAME}} page $PAGETITLE has been $CHANGEDORCREATED by $PAGEEDITOR',
 1762+'enotif_lastvisited' => 'See $1 for all changes since your last visit.',
 1763+'enotif_lastdiff' => 'See $1 to view this change.',
 1764+'enotif_anon_editor' => 'anonymous user $1',
 1765+'enotif_body' => 'Dear $WATCHINGUSERNAME,
17751766
17761767
17771768 The {{SITENAME}} page $PAGETITLE has been $CHANGEDORCREATED on $PAGEEDITDATE by $PAGEEDITOR, see $PAGETITLE_URL for the current version.
@@ -1795,149 +1786,145 @@
17961787 {{fullurl:{{MediaWiki:helppage}}}}',
17971788
17981789 # Delete/protect/revert
1799 -#
1800 -'deletepage' => 'Delete page',
1801 -'confirm' => 'Confirm',
1802 -'excontent' => "content was: '$1'",
1803 -'excontentauthor' => "content was: '$1' (and the only contributor was '[[Special:Contributions/$2|$2]]')",
1804 -'exbeforeblank' => "content before blanking was: '$1'",
1805 -'exblank' => 'page was empty',
1806 -'confirmdelete' => 'Confirm delete',
1807 -'deletesub' => "(Deleting \"$1\")",
1808 -'historywarning' => 'Warning: The page you are about to delete has a history:',
1809 -'confirmdeletetext' => "You are about to permanently delete a page
 1790+'deletepage' => 'Delete page',
 1791+'confirm' => 'Confirm',
 1792+'excontent' => "content was: '$1'",
 1793+'excontentauthor' => "content was: '$1' (and the only contributor was '[[Special:Contributions/$2|$2]]')",
 1794+'exbeforeblank' => "content before blanking was: '$1'",
 1795+'exblank' => 'page was empty',
 1796+'confirmdelete' => 'Confirm delete',
 1797+'deletesub' => '(Deleting "$1")',
 1798+'historywarning' => 'Warning: The page you are about to delete has a history:',
 1799+'confirmdeletetext' => 'You are about to permanently delete a page
18101800 or image along with all of its history from the database.
18111801 Please confirm that you intend to do this, that you understand the
18121802 consequences, and that you are doing this in accordance with
1813 -[[{{MediaWiki:policy-url}}]].",
1814 -'policy-url' => 'Project:Policy',
1815 -'actioncomplete' => 'Action complete',
1816 -'deletedtext' => "\"$1\" has been deleted.
1817 -See $2 for a record of recent deletions.",
1818 -'deletedarticle' => "deleted \"[[$1]]\"",
1819 -'dellogpage' => 'Deletion log',
1820 -'dellogpagetext' => 'Below is a list of the most recent deletions. The deletion of single revisions and events
1821 -can be reviewed by clicking the linked numbers that appear within parenthesis, which correspond to each deleted item.',
1822 -'deletionlog' => 'deletion log',
1823 -'reverted' => 'Reverted to earlier revision',
1824 -'deletecomment' => 'Reason for deletion',
1825 -'imagereverted' => 'Revert to earlier version was successful.',
1826 -'rollback' => 'Roll back edits',
1827 -'rollback_short' => 'Rollback',
1828 -'rollbacklink' => 'rollback',
1829 -'rollbackfailed' => 'Rollback failed',
1830 -'cantrollback' => 'Cannot revert edit; last contributor is only author of this page.',
1831 -'alreadyrolled' => "Cannot rollback last edit of [[:$1]]
 1803+[[{{MediaWiki:policy-url}}]].',
 1804+'actioncomplete' => 'Action complete',
 1805+'deletedtext' => '"$1" has been deleted.
 1806+See $2 for a record of recent deletions.',
 1807+'deletedarticle' => 'deleted "[[$1]]"',
 1808+'dellogpage' => 'Deletion log',
 1809+'dellogpagetext' => 'Below is a list of the most recent deletions.',
 1810+'deletionlog' => 'deletion log',
 1811+'reverted' => 'Reverted to earlier revision',
 1812+'deletecomment' => 'Reason for deletion',
 1813+'imagereverted' => 'Revert to earlier version was successful.',
 1814+'rollback' => 'Roll back edits',
 1815+'rollback_short' => 'Rollback',
 1816+'rollbacklink' => 'rollback',
 1817+'rollbackfailed' => 'Rollback failed',
 1818+'cantrollback' => 'Cannot revert edit; last contributor is only author of this page.',
 1819+'alreadyrolled' => 'Cannot rollback last edit of [[:$1]]
18321820 by [[User:$2|$2]] ([[User talk:$2|Talk]]); someone else has edited or rolled back the page already.
18331821
1834 -Last edit was by [[User:$3|$3]] ([[User talk:$3|Talk]]).",
1835 -# only shown if there is an edit comment
1836 -'editcomment' => "The edit comment was: \"<i>$1</i>\".",
1837 -'revertpage' => "Reverted edits by [[Special:Contributions/$2|$2]] ([[User talk:$2|Talk]]); changed back to last version by [[User:$1|$1]]",
1838 -'sessionfailure' => 'There seems to be a problem with your login session;
 1822+Last edit was by [[User:$3|$3]] ([[User talk:$3|Talk]]).',
 1823+'editcomment' => 'The edit comment was: "<i>$1</i>".', # only shown if there is an edit comment
 1824+'revertpage' => 'Reverted edits by [[Special:Contributions/$2|$2]] ([[User talk:$2|Talk]]); changed back to last version by [[User:$1|$1]]',
 1825+'sessionfailure' => 'There seems to be a problem with your login session;
18391826 this action has been canceled as a precaution against session hijacking.
18401827 Please hit "back" and reload the page you came from, then try again.',
1841 -'protectlogpage' => 'Protection log',
1842 -'protectlogtext' => "Below is a list of page locks and unlocks. See the [[Special:Protectedpages|protected pages list]] for the list of currently operational page protections.",
1843 -'protectedarticle' => 'protected "[[$1]]"',
1844 -'unprotectedarticle' => 'unprotected "[[$1]]"',
1845 -'protectsub' => '(Protecting "$1")',
1846 -'confirmprotecttext' => 'Do you really want to protect this page?',
1847 -'confirmprotect' => 'Confirm protection',
1848 -'protectmoveonly' => 'Protect from moves only',
1849 -'protectcomment' => 'Reason for protecting',
1850 -'protectexpiry' => 'Expiry',
1851 -'protect_expiry_invalid' => 'Expiry time is invalid.',
1852 -'protect_expiry_old' => 'Expiry time is in the past.',
1853 -'unprotectsub' =>"(Unprotecting \"$1\")",
1854 -'confirmunprotecttext' => 'Do you really want to unprotect this page?',
1855 -'confirmunprotect' => 'Confirm unprotection',
1856 -'unprotectcomment' => 'Reason for unprotecting',
1857 -'protect-unchain' => 'Unlock move permissions',
1858 -'protect-text' => 'You may view and change the protection level here for the page <strong>$1</strong>.',
1859 -'protect-locked-blocked' => 'You cannot change protection levels while blocked. Here are the
 1828+
 1829+'protectlogpage' => 'Protection log',
 1830+'protectlogtext' => 'Below is a list of page locks and unlocks. See the [[Special:Protectedpages|protected pages list]] for the list of currently operational page protections.',
 1831+'protectedarticle' => 'protected "[[$1]]"',
 1832+'modifiedarticleprotection' => 'changed protection level for "[[$1]]"',
 1833+'unprotectedarticle' => 'unprotected "[[$1]]"',
 1834+'protectsub' => '(Protecting "$1")',
 1835+'confirmprotect' => 'Confirm protection',
 1836+'protect-fileonly' => 'Apply edit restrictions to file uploads only',
 1837+'protectcomment' => 'Comment:',
 1838+'protectexpiry' => 'Expires:',
 1839+'protect_expiry_invalid' => 'Expiry time is invalid.',
 1840+'protect_expiry_old' => 'Expiry time is in the past.',
 1841+'unprotectsub' => '(Unprotecting "$1")',
 1842+'protect-unchain' => 'Unlock move permissions',
 1843+'protect-text' => 'You may view and change the protection level here for the page <strong>$1</strong>.',
 1844+'protect-locked-blocked' => 'You cannot change protection levels while blocked. Here are the
18601845 current settings for the page <strong>$1</strong>:',
1861 -'protect-locked-dblock' => 'Protection levels cannot be changed due to an active database lock.
 1846+'protect-locked-dblock' => 'Protection levels cannot be changed due to an active database lock.
18621847 Here are the current settings for the page <strong>$1</strong>:',
1863 -'protect-locked-access' => 'Your account does not have permission to change page protection levels.
 1848+'protect-locked-access' => 'Your account does not have permission to change page protection levels.
18641849 Here are the current settings for the page <strong>$1</strong>:',
1865 -'protect-cascadeon' => "This page is currently protected because it is included in the following {{PLURAL:$1|page, which has|pages, which have}} cascading protection turned on. You can change this page's protection level, but it will not affect the cascading protection.",
1866 -'protect-default' => '(default)',
 1850+'protect-cascadeon' => "This page is currently protected because it is included in the following {{PLURAL:$1|page, which has|pages, which have}} cascading protection turned on. You can change this page's protection level, but it will not affect the cascading protection.",
 1851+'protect-default' => '(default)',
18671852 'protect-level-autoconfirmed' => 'Block unregistered users',
1868 -'protect-level-sysop' => 'Sysops only',
1869 -'protect-summary-cascade' => 'cascading',
1870 -'protect-expiring' => 'expires $1 (UTC)',
1871 -'protect-cascade' => 'Cascading protection - protect any pages included in this page.',
1872 -'restriction-type' => 'Permission:',
1873 -'restriction-level' => 'Restriction level:',
1874 -'minimum-size' => 'Min size',
1875 -'maximum-size' => 'Max size',
1876 -'pagesize' => '(bytes)',
 1853+'protect-level-sysop' => 'Sysops only',
 1854+'protect-summary-cascade' => 'cascading',
 1855+'protect-expiring' => 'expires $1 (UTC)',
 1856+'protect-cascade' => 'Protect pages included in this page (cascading protection)',
 1857+'restriction-type' => 'Permission:',
 1858+'restriction-level' => 'Restriction level:',
 1859+'minimum-size' => 'Min size',
 1860+'maximum-size' => 'Max size',
 1861+'pagesize' => '(bytes)',
18771862
1878 -# restrictions (nouns)
 1863+# Restrictions (nouns)
18791864 'restriction-edit' => 'Edit',
18801865 'restriction-move' => 'Move',
 1866+'restriction-upload' => 'Upload',
18811867
1882 -# restriction levels
1883 -'restriction-level-sysop' => 'full protected',
 1868+# Restriction levels
 1869+'restriction-level-sysop' => 'full protected',
18841870 'restriction-level-autoconfirmed' => 'semi protected',
1885 -'restriction-level-all' => 'any level',
 1871+'restriction-level-all' => 'any level',
18861872
1887 -
18881873 # Undelete
1889 -'undelete' => 'View deleted pages',
1890 -'undeletepage' => 'View and restore deleted pages',
1891 -'viewdeletedpage' => 'View deleted pages',
1892 -'undeletepagetext' => 'The following pages have been deleted but are still in the archive and
 1874+'undelete' => 'View deleted pages',
 1875+'undeletepage' => 'View and restore deleted pages',
 1876+'viewdeletedpage' => 'View deleted pages',
 1877+'undeletepagetitle' => '\'\'\'The following list consists of deleted revisions of [[$1]]\'\'\'.',
 1878+'undeletepagetext' => 'The following pages have been deleted but are still in the archive and
18931879 can be restored. The archive may be periodically cleaned out.',
1894 -'undeleteextrahelp' => "To restore the entire page, leave all radios deselected and click '''''Restore'''''.
 1880+'undeleteextrahelp' => "To restore the entire page, leave all radios deselected and click '''''Restore'''''.
18951881 To perform a selective restoration, check the desired restore point below and click '''''Restore'''''.
18961882 Clicking '''''Reset''''' will reset this form. Note that you will have to re-select any options if you
18971883 use the navigation links.",
1898 -'undeleterevisions' => "$1 {{PLURAL:$1|revision|revisions}} archived",
1899 -'undeletehistory' => 'If you restore the page, these revisions will be restored to the page history.
1900 -If a new page with the same name has been created since the deletion, the restored revisions will appear
1901 -in the prior history.',
1902 -'undeleterevdel' => 'Undeletion will not be performed if either it would result in the top page or image revision
1903 -being restricted or it would result in an alternating page history between these and any live revisions for this page. ',
1904 -'restorepoint' => 'Use the radio button column to restore only revisions from the specified time onwards.',
1905 -'restorenone' => '(select this button to restore none of these revisions)',
1906 -'undeletehistorynoadmin' => 'This article has been deleted. The reason for deletion is
 1884+'undeleterevisions' => '$1 {{PLURAL:$1|revision|revisions}} archived',
 1885+'undeletehistory' => 'If you restore the page, all revisions will be restored to the history.
 1886+If a new page with the same name has been created since the deletion, the restored
 1887+revisions will appear in the prior history, and the current revision of the live page
 1888+will not be automatically replaced. Also note that restrictions on file revisions are lost upon restoration',
 1889+'undeleterevdel' => 'Undeletion will not be performed if either it would result in the top page or image revision
 1890+being restricted or it would result in an alternating page history between these and any live revisions for this page.',
 1891+'undeletehistorynoadmin' => 'This article has been deleted. The reason for deletion is
19071892 shown in the summary below, along with details of the users who had edited this page
19081893 before deletion. The actual text of these deleted revisions is only available to administrators.',
1909 -'undelete-revision' => 'Deleted revision of $1 from $2:',
1910 -'undeleterevision-missing' => "Invalid or missing revision. You may have a bad link, or the
1911 -revision may have been restored or removed from the archive.",
1912 -'undeletebtn' => 'Restore',
1913 -'undeletereset' => 'Reset',
1914 -'undeletecomment' => 'Comment:',
1915 -'undeletedarticle' => "restored \"[[$1]]\"",
1916 -'undeletedrevisions' => "$1 {{PLURAL:$1|revision|revisions}} restored",
1917 -'undeletedrevisions-files' => "$1 {{PLURAL:$1|revision|revisions}} and $2 {{PLURAL:$2|file|files}} restored",
1918 -'undeletedfiles' => "$1 {{PLURAL:$1|file|files}} restored",
1919 -'cannotundelete' => 'Undelete failed; someone else may have undeleted the page first.',
1920 -'undeletedpage' => "<big>'''$1 has been restored'''</big>
 1894+'restorepoint' => 'Use the radio button column to restore only revisions from the specified time onwards.',
 1895+'restorenone' => '(select this button to restore none of these revisions)',
19211896
 1897+'undelete-revision' => 'Deleted revision of $1 from $2:',
 1898+'undeleterevision-missing' => 'Invalid or missing revision. You may have a bad link, or the
 1899+revision may have been restored or removed from the archive.',
 1900+'undeletebtn' => 'Restore',
 1901+'undeletereset' => 'Reset',
 1902+'undeletecomment' => 'Comment:',
 1903+'undeletedarticle' => 'restored "[[$1]]"',
 1904+'undeletedrevisions' => '$1 {{PLURAL:$1|revision|revisions}} restored',
 1905+'undeletedrevisions-files' => '$1 {{PLURAL:$1|revision|revisions}} and $2 {{PLURAL:$2|file|files}} restored',
 1906+'undeletedfiles' => '$1 {{PLURAL:$1|file|files}} restored',
 1907+'cannotundelete' => 'Undelete failed; someone else may have undeleted the page first.',
 1908+'undeletedpage' => "<big>'''$1 has been restored'''</big>
 1909+
19221910 Consult the [[Special:Log/delete|deletion log]] for a record of recent deletions and restorations.",
1923 -'undelete-header' => 'See [[Special:Log/delete|the deletion log]] for recently deleted pages or revisions.',
1924 -'undelete-search-box' => 'Search deleted pages',
1925 -'undelete-search-prefix' => 'Show pages starting with:',
1926 -'undelete-search-submit' => 'Search',
1927 -'undelete-no-results' => 'No matching pages found in the deletion archive.',
 1911+'undelete-header' => 'See [[Special:Log/delete|the deletion log]] for recently deleted pages.',
 1912+'undelete-search-box' => 'Search deleted pages',
 1913+'undelete-search-prefix' => 'Show pages starting with:',
 1914+'undelete-search-submit' => 'Search',
 1915+'undelete-no-results' => 'No matching pages found in the deletion archive.',
19281916
19291917 # Namespace form on various pages
19301918 'namespace' => 'Namespace:',
1931 -'invert' => 'Invert selection',
 1919+'invert' => 'Invert selection',
19321920
19331921 # Contributions
1934 -#
19351922 'contributions' => 'User contributions',
19361923 'mycontris' => 'My contributions',
1937 -'contribsub2' => "For $1 ($2)",
 1924+'contribsub2' => 'For $1 ($2)',
19381925 'nocontribs' => 'No changes were found matching these criteria.',
19391926 'ucnote' => "Below are this user's last <b>$1</b> changes in the last <b>$2</b> days.",
1940 -'uclinks' => "View the last $1 changes; view the last $2 days.",
1941 -'uctop' => ' (top)' ,
 1927+'uclinks' => 'View the last $1 changes; view the last $2 days.',
 1928+'uctop' => ' (top)',
19421929
19431930 'sp-contributions-newest' => 'Newest',
19441931 'sp-contributions-oldest' => 'Oldest',
@@ -1949,16 +1936,15 @@
19501937 'sp-contributions-search' => 'Search for contributions',
19511938 'sp-contributions-username' => 'IP Address or username:',
19521939 'sp-contributions-submit' => 'Search',
1953 -'sp-contributions-footer' => '-',
1954 -'sp-contributions-footer-anon' => '-',
 1940+'sp-contributions-footer' => '-', # don't translate or duplicate this message to other languages
 1941+'sp-contributions-footer-anon' => '-', # don't translate or duplicate this message to other languages
19551942
19561943 'sp-newimages-showfrom' => 'Show new images starting from $1',
19571944
19581945 # What links here
1959 -#
19601946 'whatlinkshere' => 'What links here',
1961 -'whatlinkshere-summary' => '',
1962 -'whatlinkshere-barrow' => '&lt;',
 1947+'whatlinkshere-summary' => '', # only translate this message to other languages if you have to change it
 1948+'whatlinkshere-barrow' => '&lt;', # only translate this message to other languages if you have to change it
19631949 'notargettitle' => 'No target',
19641950 'notargettext' => 'You have not specified a target page or user
19651951 to perform this function on.',
@@ -1970,21 +1956,21 @@
19711957 'istemplate' => 'inclusion',
19721958 'whatlinkshere-prev' => '{{PLURAL:$1|previous|previous $1}}',
19731959 'whatlinkshere-next' => '{{PLURAL:$1|next|next $1}}',
 1960+'whatlinkshere-links' => '← links',
19741961
1975 -# Block/unblock IP
1976 -#
1977 -'blockip' => 'Block user',
1978 -'blockiptext' => "Use the form below to block write access
 1962+# Block/unblock
 1963+'blockip' => 'Block user',
 1964+'blockiptext' => 'Use the form below to block write access
19791965 from a specific IP address or username.
19801966 This should be done only to prevent vandalism, and in
19811967 accordance with [[{{MediaWiki:policy-url}}|policy]].
19821968 Fill in a specific reason below (for example, citing particular
1983 -pages that were vandalized).",
1984 -'ipaddress' => 'IP Address:',
1985 -'ipadressorusername' => 'IP Address or username:',
1986 -'ipbexpiry' => 'Expiry:',
1987 -'ipbreason' => 'Reason:',
1988 -'ipbreasonotherlist' => 'Other reason',
 1969+pages that were vandalized).',
 1970+'ipaddress' => 'IP Address:',
 1971+'ipadressorusername' => 'IP Address or username:',
 1972+'ipbexpiry' => 'Expiry:',
 1973+'ipbreason' => 'Reason:',
 1974+'ipbreasonotherlist' => 'Other reason',
19891975
19901976 // These are examples only. They can be translated but should be adjusted via
19911977 // [[MediaWiki:ipbreason-list]] by the local community
@@ -1992,7 +1978,7 @@
19931979 // * defines a block reason group in the drow down menu
19941980 // ** defines a block reason
19951981 // To disable this drop down menu enter '-' in [[MediaWiki:ipbreason-dropdown]].
1996 -'ipbreason-dropdown' => '
 1982+'ipbreason-dropdown' => '
19971983 *Common block reasons
19981984 ** Inserting false information
19991985 ** Removing content from pages
@@ -2001,97 +1987,97 @@
20021988 ** Intimidating behaviour/harassment
20031989 ** Abusing multiple accounts
20041990 ** Unacceptable username',
2005 -'ipbanononly' => 'Block anonymous users only',
2006 -'ipbcreateaccount' => 'Prevent account creation',
2007 -'ipbenableautoblock' => 'Automatically block the last IP address used by this user, and any subsequent IPs they try to edit from',
2008 -'ipbsubmit' => 'Block this user',
2009 -'ipbother' => 'Other time:',
2010 -'ipboptions' => '2 hours:2 hours,1 day:1 day,3 days:3 days,1 week:1 week,2 weeks:2 weeks,1 month:1 month,3 months:3 months,6 months:6 months,1 year:1 year,infinite:infinite',
2011 -'ipbotheroption' => 'other',
2012 -'ipbotherreason' => 'Other/additional reason:',
2013 -'ipbhidename' => 'Hide username/IP from the block log, active block list and user list',
2014 -'badipaddress' => 'Invalid IP address',
2015 -'blockipsuccesssub' => 'Block succeeded',
2016 -'blockipsuccesstext' => '[[Special:Contributions/$1|$1]] has been blocked.
 1991+'ipbanononly' => 'Block anonymous users only',
 1992+'ipbcreateaccount' => 'Prevent account creation',
 1993+'ipbemailban' => 'Prevent user from sending e-mail',
 1994+'ipbenableautoblock' => 'Automatically block the last IP address used by this user, and any subsequent IPs they try to edit from',
 1995+'ipbsubmit' => 'Block this user',
 1996+'ipbother' => 'Other time:',
 1997+'ipboptions' => '2 hours:2 hours,1 day:1 day,3 days:3 days,1 week:1 week,2 weeks:2 weeks,1 month:1 month,3 months:3 months,6 months:6 months,1 year:1 year,infinite:infinite',
 1998+'ipbotheroption' => 'other',
 1999+'ipbotherreason' => 'Other/additional reason:',
 2000+'ipbhidename' => 'Hide username/IP from the block log, active block list and user list',
 2001+'badipaddress' => 'Invalid IP address',
 2002+'blockipsuccesssub' => 'Block succeeded',
 2003+'blockipsuccesstext' => '[[Special:Contributions/$1|$1]] has been blocked.
20172004 <br />See [[Special:Ipblocklist|IP block list]] to review blocks.',
2018 -'ipb-edit-dropdown' => 'Edit block reasons',
2019 -'ipb-unblock-addr' => 'Unblock $1',
2020 -'ipb-unblock' => 'Unblock a username or IP address',
2021 -'ipb-blocklist-addr' => 'View existing blocks for $1',
2022 -'ipb-blocklist' => 'View existing blocks',
2023 -'unblockip' => 'Unblock user',
2024 -'unblockiptext' => 'Use the form below to restore write access
 2005+'ipb-edit-dropdown' => 'Edit block reasons',
 2006+'ipb-unblock-addr' => 'Unblock $1',
 2007+'ipb-unblock' => 'Unblock a username or IP address',
 2008+'ipb-blocklist-addr' => 'View existing blocks for $1',
 2009+'ipb-blocklist' => 'View existing blocks',
 2010+'unblockip' => 'Unblock user',
 2011+'unblockiptext' => 'Use the form below to restore write access
20252012 to a previously blocked IP address or username.',
2026 -'ipusubmit' => 'Unblock this address',
2027 -'unblocked' => '[[User:$1|$1]] has been unblocked',
2028 -'unblocked-id' => 'Block $1 has been removed',
2029 -'ipblocklist' => 'List of blocked IP addresses and usernames',
2030 -'ipblocklist-summary' => '',
2031 -'ipblocklist-submit' => 'Search',
2032 -'blocklistline' => "$1, $2 blocked $3 ($4)",
2033 -'infiniteblock' => 'infinite',
2034 -'expiringblock' => 'expires $1',
2035 -'anononlyblock' => 'anon. only',
2036 -'noautoblockblock' => 'autoblock disabled',
2037 -'createaccountblock' => 'account creation blocked',
2038 -'ipblocklist-empty' => 'The blocklist is empty.',
2039 -'ipblocklist-no-results' => 'The requested IP address or username is not blocked.',
2040 -'blocklink' => 'block',
2041 -'unblocklink' => 'unblock',
2042 -'contribslink' => 'contribs',
2043 -'autoblocker' => 'Autoblocked because your IP address has been recently used by "[[User:$1|$1]]". The reason given for $1\'s block is: "$2"',
2044 -'blocklogpage' => 'Block log',
2045 -'blocklogentry' => 'blocked "[[$1]]" with an expiry time of $2 $3',
2046 -'blocklogtext' => 'This is a log of user blocking and unblocking actions. Automatically
 2013+'ipusubmit' => 'Unblock this address',
 2014+'unblocked' => '[[User:$1|$1]] has been unblocked',
 2015+'unblocked-id' => 'Block $1 has been removed',
 2016+'ipblocklist' => 'List of blocked IP addresses and usernames',
 2017+'ipblocklist-summary' => '', # only translate this message to other languages if you have to change it
 2018+'ipblocklist-submit' => 'Search',
 2019+'blocklistline' => '$1, $2 blocked $3 ($4)',
 2020+'infiniteblock' => 'infinite',
 2021+'expiringblock' => 'expires $1',
 2022+'anononlyblock' => 'anon. only',
 2023+'noautoblockblock' => 'autoblock disabled',
 2024+'createaccountblock' => 'account creation blocked',
 2025+'emailblock' => 'e-mail blocked',
 2026+'ipblocklist-empty' => 'The blocklist is empty.',
 2027+'ipblocklist-no-results' => 'The requested IP address or username is not blocked.',
 2028+'blocklink' => 'block',
 2029+'unblocklink' => 'unblock',
 2030+'contribslink' => 'contribs',
 2031+'autoblocker' => 'Autoblocked because your IP address has been recently used by "[[User:$1|$1]]". The reason given for $1\'s block is: "$2"',
 2032+'blocklogpage' => 'Block log',
 2033+'blocklogentry' => 'blocked "[[$1]]" with an expiry time of $2 $3',
 2034+'blocklogtext' => 'This is a log of user blocking and unblocking actions. Automatically
20472035 blocked IP addresses are not listed. See the [[Special:Ipblocklist|IP block list]] for
20482036 the list of currently operational bans and blocks.',
2049 -'unblocklogentry' => 'unblocked $1',
2050 -'block-log-flags-anononly' => 'anonymous users only',
2051 -'block-log-flags-nocreate' => 'account creation disabled',
 2037+'unblocklogentry' => 'unblocked $1',
 2038+'block-log-flags-anononly' => 'anonymous users only',
 2039+'block-log-flags-nocreate' => 'account creation disabled',
20522040 'block-log-flags-noautoblock' => 'autoblock disabled',
2053 -'range_block_disabled' => 'The sysop ability to create range blocks is disabled.',
2054 -'ipb_expiry_invalid' => 'Expiry time invalid.',
2055 -'ipb_already_blocked' => '"$1" is already blocked',
2056 -'ip_range_invalid' => 'Invalid IP range.',
2057 -'proxyblocker' => 'Proxy blocker',
2058 -'ipb_cant_unblock' => 'Error: Block ID $1 not found. It may have been unblocked already.',
2059 -'proxyblockreason' => 'Your IP address has been blocked because it is an open proxy. Please contact your Internet service provider or tech support and inform them of this serious security problem.',
2060 -'proxyblocksuccess' => 'Done.',
2061 -'sorbs' => 'DNSBL',
2062 -'sorbsreason' => 'Your IP address is listed as an open proxy in the DNSBL used by this site.',
 2041+'block-log-flags-noemail' => 'e-mail blocked',
 2042+'range_block_disabled' => 'The sysop ability to create range blocks is disabled.',
 2043+'ipb_expiry_invalid' => 'Expiry time invalid.',
 2044+'ipb_already_blocked' => '"$1" is already blocked',
 2045+'ip_range_invalid' => 'Invalid IP range.',
 2046+'proxyblocker' => 'Proxy blocker',
 2047+'ipb_cant_unblock' => 'Error: Block ID $1 not found. It may have been unblocked already.',
 2048+'proxyblockreason' => 'Your IP address has been blocked because it is an open proxy. Please contact your Internet service provider or tech support and inform them of this serious security problem.',
 2049+'proxyblocksuccess' => 'Done.',
 2050+'sorbs' => 'DNSBL',
 2051+'sorbsreason' => 'Your IP address is listed as an open proxy in the DNSBL used by this site.',
20632052 'sorbs_create_account_reason' => 'Your IP address is listed as an open proxy in the DNSBL used by this site. You cannot create an account',
20642053
2065 -
20662054 # Developer tools
2067 -#
2068 -'lockdb' => 'Lock database',
2069 -'unlockdb' => 'Unlock database',
2070 -'lockdbtext' => 'Locking the database will suspend the ability of all
 2055+'lockdb' => 'Lock database',
 2056+'unlockdb' => 'Unlock database',
 2057+'lockdbtext' => 'Locking the database will suspend the ability of all
20712058 users to edit pages, change their preferences, edit their watchlists, and
20722059 other things requiring changes in the database.
20732060 Please confirm that this is what you intend to do, and that you will
20742061 unlock the database when your maintenance is done.',
2075 -'unlockdbtext' => 'Unlocking the database will restore the ability of all
 2062+'unlockdbtext' => 'Unlocking the database will restore the ability of all
20762063 users to edit pages, change their preferences, edit their watchlists, and
20772064 other things requiring changes in the database.
20782065 Please confirm that this is what you intend to do.',
2079 -'lockconfirm' => 'Yes, I really want to lock the database.',
2080 -'unlockconfirm' => 'Yes, I really want to unlock the database.',
2081 -'lockbtn' => 'Lock database',
2082 -'unlockbtn' => 'Unlock database',
2083 -'locknoconfirm' => 'You did not check the confirmation box.',
2084 -'lockdbsuccesssub' => 'Database lock succeeded',
2085 -'unlockdbsuccesssub' => 'Database lock removed',
2086 -'lockdbsuccesstext' => 'The database has been locked.
 2066+'lockconfirm' => 'Yes, I really want to lock the database.',
 2067+'unlockconfirm' => 'Yes, I really want to unlock the database.',
 2068+'lockbtn' => 'Lock database',
 2069+'unlockbtn' => 'Unlock database',
 2070+'locknoconfirm' => 'You did not check the confirmation box.',
 2071+'lockdbsuccesssub' => 'Database lock succeeded',
 2072+'unlockdbsuccesssub' => 'Database lock removed',
 2073+'lockdbsuccesstext' => 'The database has been locked.
20872074 <br />Remember to [[Special:Unlockdb|remove the lock]] after your maintenance is complete.',
20882075 'unlockdbsuccesstext' => 'The database has been unlocked.',
20892076 'lockfilenotwritable' => 'The database lock file is not writable. To lock or unlock the database, this needs to be writable by the web server.',
2090 -'databasenotlocked' => 'The database is not locked.',
 2077+'databasenotlocked' => 'The database is not locked.',
20912078
20922079 # Move page
2093 -#
2094 -'movepage' => 'Move page',
2095 -'movepagetext' => 'Using the form below will rename a page, moving all
 2080+'movepage' => 'Move page',
 2081+'movepagetext' => "Using the form below will rename a page, moving all
20962082 of its history to the new name.
20972083 The old title will become a redirect page to the new title.
20982084 Links to the old page title will not be changed; be sure to
@@ -2099,7 +2085,7 @@
21002086 You are responsible for making sure that links continue to
21012087 point where they are supposed to go.
21022088
2103 -Note that the page will \'\'\'not\'\'\' be moved if there is already
 2089+Note that the page will '''not''' be moved if there is already
21042090 a page at the new title, unless it is empty or a redirect and has no
21052091 past edit history. This means that you can rename a page back to where
21062092 it was just renamed from if you make a mistake, and you cannot overwrite
@@ -2108,49 +2094,47 @@
21092095 <b>WARNING!</b>
21102096 This can be a drastic and unexpected change for a popular page;
21112097 please be sure you understand the consequences of this before
2112 -proceeding.',
2113 -'movepagetalktext' => 'The associated talk page will be automatically moved along with it \'\'\'unless:\'\'\'
 2098+proceeding.",
 2099+'movepagetalktext' => "The associated talk page will be automatically moved along with it '''unless:'''
21142100 *A non-empty talk page already exists under the new name, or
21152101 *You uncheck the box below.
21162102
2117 -In those cases, you will have to move or merge the page manually if desired.',
2118 -'movearticle' => 'Move page',
2119 -'movenologin' => 'Not logged in',
2120 -'movenologintext' => "You must be a registered user and [[Special:Userlogin|logged in]]
2121 -to move a page.",
2122 -'newtitle' => 'To new title',
2123 -'move-watch' => 'Watch this page',
2124 -'movepagebtn' => 'Move page',
2125 -'pagemovedsub' => 'Move succeeded',
2126 -'pagemovedtext' => "Page \"[[$1]]\" moved to \"[[$2]]\".",
2127 -'articleexists' => 'A page of that name already exists, or the
 2103+In those cases, you will have to move or merge the page manually if desired.",
 2104+'movearticle' => 'Move page',
 2105+'movenologin' => 'Not logged in',
 2106+'movenologintext' => 'You must be a registered user and [[Special:Userlogin|logged in]]
 2107+to move a page.',
 2108+'newtitle' => 'To new title',
 2109+'move-watch' => 'Watch this page',
 2110+'movepagebtn' => 'Move page',
 2111+'pagemovedsub' => 'Move succeeded',
 2112+'pagemovedtext' => 'Page "[[$1]]" moved to "[[$2]]".',
 2113+'articleexists' => 'A page of that name already exists, or the
21282114 name you have chosen is not valid.
21292115 Please choose another name.',
2130 -'talkexists' => "'''The page itself was moved successfully, but the talk page could not be moved because one already exists at the new title. Please merge them manually.'''",
2131 -'movedto' => 'moved to',
2132 -'movetalk' => 'Move associated talk page',
2133 -'talkpagemoved' => 'The corresponding talk page was also moved.',
2134 -'talkpagenotmoved' => 'The corresponding talk page was <strong>not</strong> moved.',
2135 -'1movedto2' => '[[$1]] moved to [[$2]]',
2136 -'1movedto2_redir' => '[[$1]] moved to [[$2]] over redirect',
2137 -'movelogpage' => 'Move log',
2138 -'movelogpagetext' => 'Below is a list of page moved.',
2139 -'movereason' => 'Reason',
2140 -'revertmove' => 'revert',
2141 -'delete_and_move' => 'Delete and move',
2142 -'delete_and_move_text' =>
2143 -'==Deletion required==
 2116+'talkexists' => "'''The page itself was moved successfully, but the talk page could not be moved because one already exists at the new title. Please merge them manually.'''",
 2117+'movedto' => 'moved to',
 2118+'movetalk' => 'Move associated talk page',
 2119+'talkpagemoved' => 'The corresponding talk page was also moved.',
 2120+'talkpagenotmoved' => 'The corresponding talk page was <strong>not</strong> moved.',
 2121+'1movedto2' => '[[$1]] moved to [[$2]]',
 2122+'1movedto2_redir' => '[[$1]] moved to [[$2]] over redirect',
 2123+'movelogpage' => 'Move log',
 2124+'movelogpagetext' => 'Below is a list of page moved.',
 2125+'movereason' => 'Reason',
 2126+'revertmove' => 'revert',
 2127+'delete_and_move' => 'Delete and move',
 2128+'delete_and_move_text' => '==Deletion required==
21442129
21452130 The destination article "[[$1]]" already exists. Do you want to delete it to make way for the move?',
21462131 'delete_and_move_confirm' => 'Yes, delete the page',
2147 -'delete_and_move_reason' => 'Deleted to make way for move',
2148 -'selfmove' => "Source and destination titles are the same; can't move a page over itself.",
2149 -'immobile_namespace' => "Source or destination title is of a special type; cannot move pages from and into that namespace.",
 2132+'delete_and_move_reason' => 'Deleted to make way for move',
 2133+'selfmove' => "Source and destination titles are the same; can't move a page over itself.",
 2134+'immobile_namespace' => 'Source or destination title is of a special type; cannot move pages from and into that namespace.',
21502135
21512136 # Export
2152 -
2153 -'export' => 'Export pages',
2154 -'exporttext' => 'You can export the text and editing history of a particular page or
 2137+'export' => 'Export pages',
 2138+'exporttext' => 'You can export the text and editing history of a particular page or
21552139 set of pages wrapped in some XML. This can be imported into another wiki using MediaWiki
21562140 via the [[Special:Import|import page]].
21572141
@@ -2159,314 +2143,311 @@
21602144 history lines, or just the current version with the info about the last edit.
21612145
21622146 In the latter case you can also use a link, e.g. [[{{ns:Special}}:Export/{{MediaWiki:mainpage}}]] for the page {{MediaWiki:mainpage}}.',
2163 -'exportcuronly' => 'Include only the current revision, not the full history',
2164 -'exportnohistory' => "----
 2147+'exportcuronly' => 'Include only the current revision, not the full history',
 2148+'exportnohistory' => "----
21652149 '''Note:''' Exporting the full history of pages through this form has been disabled due to performance reasons.",
2166 -'export-submit' => 'Export',
 2150+'export-submit' => 'Export',
21672151 'export-addcattext' => 'Add pages from category:',
2168 -'export-addcat' => 'Add',
 2152+'export-addcat' => 'Add',
21692153
21702154 # Namespace 8 related
2171 -
2172 -'allmessages' => 'System messages',
2173 -'allmessagesname' => 'Name',
2174 -'allmessagesdefault' => 'Default text',
2175 -'allmessagescurrent' => 'Current text',
2176 -'allmessagestext' => 'This is a list of system messages available in the MediaWiki namespace.',
 2155+'allmessages' => 'System messages',
 2156+'allmessagesname' => 'Name',
 2157+'allmessagesdefault' => 'Default text',
 2158+'allmessagescurrent' => 'Current text',
 2159+'allmessagestext' => 'This is a list of system messages available in the MediaWiki namespace.',
21772160 'allmessagesnotsupportedUI' => 'Your current interface language <b>$1</b> is not supported by {{ns:special}}:Allmessages at this site.',
2178 -'allmessagesnotsupportedDB' => '\'\'\'{{ns:special}}:Allmessages\'\'\' cannot be used because \'\'\'$wgUseDatabaseMessages\'\'\' is switched off.',
2179 -'allmessagesfilter' => 'Message name filter:',
2180 -'allmessagesmodified' => 'Show only modified',
 2161+'allmessagesnotsupportedDB' => "'''{{ns:special}}:Allmessages''' cannot be used because '''\$wgUseDatabaseMessages''' is switched off.",
 2162+'allmessagesfilter' => 'Message name filter:',
 2163+'allmessagesmodified' => 'Show only modified',
21812164
2182 -
21832165 # Thumbnails
2184 -
2185 -'thumbnail-more' => 'Enlarge',
2186 -'missingimage' => '<b>Missing image</b><br /><i>$1</i>',
2187 -'filemissing' => 'File missing',
2188 -'thumbnail_error' => 'Error creating thumbnail: $1',
2189 -'djvu_page_error' => 'DjVu page out of range',
2190 -'djvu_no_xml' => 'Unable to fetch XML for DjVu file',
 2166+'thumbnail-more' => 'Enlarge',
 2167+'missingimage' => '<b>Missing image</b><br /><i>$1</i>',
 2168+'filemissing' => 'File missing',
 2169+'thumbnail_error' => 'Error creating thumbnail: $1',
 2170+'djvu_page_error' => 'DjVu page out of range',
 2171+'djvu_no_xml' => 'Unable to fetch XML for DjVu file',
21912172 'thumbnail_invalid_params' => 'Invalid thumbnail parameters',
21922173 'thumbnail_dest_directory' => 'Unable to create destination directory',
21932174
21942175 # Special:Import
2195 -'import' => 'Import pages',
2196 -'importinterwiki' => 'Transwiki import',
2197 -'import-interwiki-text' => 'Select a wiki and page title to import.
2198 -Revision dates and editors\' names will be preserved.
2199 -All transwiki import actions are logged at the [[Special:Log/import|import log]].',
2200 -'import-interwiki-history' => 'Copy all history versions for this page',
2201 -'import-interwiki-submit' => 'Import',
 2176+'import' => 'Import pages',
 2177+'importinterwiki' => 'Transwiki import',
 2178+'import-interwiki-text' => "Select a wiki and page title to import.
 2179+Revision dates and editors' names will be preserved.
 2180+All transwiki import actions are logged at the [[Special:Log/import|import log]].",
 2181+'import-interwiki-history' => 'Copy all history versions for this page',
 2182+'import-interwiki-submit' => 'Import',
22022183 'import-interwiki-namespace' => 'Transfer pages into namespace:',
2203 -'importtext' => 'Please export the file from the source wiki using the Special:Export utility, save it to
2204 -your disk and upload it here. Note that if the page used by an imported revision already exists, the revision
2205 -will only be inserted if it is newer than or predates the page history.',
2206 -'importstart' => "Importing pages...",
2207 -'import-revision-count' => '$1 {{PLURAL:$1|revision|revisions}}',
2208 -'importnopages' => "No pages to import.",
2209 -'importfailed' => "Import failed: $1",
2210 -'importunknownsource' => "Unknown import source type",
2211 -'importcantopen' => "Couldn't open import file",
2212 -'importbadinterwiki' => "Bad interwiki link",
2213 -'importnotext' => 'Empty or no text',
2214 -'importsuccess' => 'Import succeeded!',
2215 -'importhistoryconflict' => 'Conflicting history revision exists (may have imported this page before)',
2216 -'importnosources' => 'No transwiki import sources have been defined and direct history uploads are disabled.',
2217 -'importnofile' => 'No import file was uploaded.',
2218 -'importuploaderror' => 'Upload of import file failed; perhaps the file is bigger than the allowed upload size.',
 2184+'importtext' => 'Please export the file from the source wiki using the Special:Export utility, save it to your disk and upload it here.',
 2185+'importstart' => 'Importing pages...',
 2186+'import-revision-count' => '$1 {{PLURAL:$1|revision|revisions}}',
 2187+'importnopages' => 'No pages to import.',
 2188+'importfailed' => 'Import failed: $1',
 2189+'importunknownsource' => 'Unknown import source type',
 2190+'importcantopen' => "Couldn't open import file",
 2191+'importbadinterwiki' => 'Bad interwiki link',
 2192+'importnotext' => 'Empty or no text',
 2193+'importsuccess' => 'Import succeeded!',
 2194+'importhistoryconflict' => 'Conflicting history revision exists (may have imported this page before)',
 2195+'importnosources' => 'No transwiki import sources have been defined and direct history uploads are disabled.',
 2196+'importnofile' => 'No import file was uploaded.',
 2197+'importuploaderror' => 'Upload of import file failed; perhaps the file is bigger than the allowed upload size.',
22192198
2220 -# import log
2221 -'importlogpage' => 'Import log',
2222 -'importlogpagetext' => 'Administrative imports of pages with edit history from other wikis.',
2223 -'import-logentry-upload' => 'imported [[$1]] by file upload',
2224 -'import-logentry-upload-detail' => '$1 revision(s)',
2225 -'import-logentry-interwiki' => 'transwikied $1',
 2199+# Import log
 2200+'importlogpage' => 'Import log',
 2201+'importlogpagetext' => 'Administrative imports of pages with edit history from other wikis.',
 2202+'import-logentry-upload' => 'imported [[$1]] by file upload',
 2203+'import-logentry-upload-detail' => '$1 revision(s)',
 2204+'import-logentry-interwiki' => 'transwikied $1',
22262205 'import-logentry-interwiki-detail' => '$1 revision(s) from $2',
22272206
2228 -
22292207 # Keyboard access keys for power users
2230 -'accesskey-pt-userpage' => '.',
2231 -'accesskey-pt-anonuserpage' => '.',
2232 -'accesskey-pt-mytalk' => 'n',
2233 -'accesskey-pt-anontalk' => 'n',
2234 -'accesskey-pt-preferences' => '',
2235 -'accesskey-pt-watchlist' => 'l',
2236 -'accesskey-pt-mycontris' => 'y',
2237 -'accesskey-pt-login' => 'o',
2238 -'accesskey-pt-anonlogin' => 'o',
2239 -'accesskey-pt-logout' => '',
2240 -'accesskey-ca-talk' => 't',
2241 -'accesskey-ca-edit' => 'e',
2242 -'accesskey-ca-addsection' => '+',
2243 -'accesskey-ca-viewsource' => 'e',
2244 -'accesskey-ca-history' => 'h',
2245 -'accesskey-ca-protect' => '=',
2246 -'accesskey-ca-delete' => 'd',
2247 -'accesskey-ca-undelete' => 'd',
2248 -'accesskey-ca-move' => 'm',
2249 -'accesskey-ca-watch' => 'w',
2250 -'accesskey-ca-unwatch' => 'w',
2251 -'accesskey-search' => 'f',
2252 -'accesskey-p-logo' => '',
2253 -'accesskey-n-mainpage' => 'z',
2254 -'accesskey-n-portal' => '',
2255 -'accesskey-n-currentevents' => '',
2256 -'accesskey-n-recentchanges' => 'r',
2257 -'accesskey-n-randompage' => 'x',
2258 -'accesskey-n-help' => '',
2259 -'accesskey-n-sitesupport' => '',
2260 -'accesskey-t-whatlinkshere' => 'j',
2261 -'accesskey-t-recentchangeslinked' => 'k',
2262 -'accesskey-feed-rss' => '',
2263 -'accesskey-feed-atom' => '',
2264 -'accesskey-t-contributions' => '',
2265 -'accesskey-t-emailuser' => '',
2266 -'accesskey-t-permalink' => '',
2267 -'accesskey-t-print' => 'p',
2268 -'accesskey-t-upload' => 'u',
2269 -'accesskey-t-specialpages' => 'q',
2270 -'accesskey-ca-nstab-main' => 'c',
2271 -'accesskey-ca-nstab-user' => 'c',
2272 -'accesskey-ca-nstab-media' => 'c',
2273 -'accesskey-ca-nstab-special' => '',
2274 -'accesskey-ca-nstab-project' => 'a',
2275 -'accesskey-ca-nstab-image' => 'c',
2276 -'accesskey-ca-nstab-mediawiki' => 'c',
2277 -'accesskey-ca-nstab-template' => 'c',
2278 -'accesskey-ca-nstab-help' => 'c',
2279 -'accesskey-ca-nstab-category' => 'c',
2280 -'accesskey-minoredit' => 'i',
2281 -'accesskey-save' => 's',
2282 -'accesskey-preview' => 'p',
2283 -'accesskey-diff' => 'v',
2284 -'accesskey-compareselectedversions' => 'v',
2285 -'accesskey-watch' => 'w',
 2208+'accesskey-pt-userpage' => '.', # don't translate or duplicate this message to other languages
 2209+'accesskey-pt-anonuserpage' => '.', # don't translate or duplicate this message to other languages
 2210+'accesskey-pt-mytalk' => 'n', # don't translate or duplicate this message to other languages
 2211+'accesskey-pt-anontalk' => 'n', # don't translate or duplicate this message to other languages
 2212+'accesskey-pt-preferences' => '', # don't translate or duplicate this message to other languages
 2213+'accesskey-pt-watchlist' => 'l', # don't translate or duplicate this message to other languages
 2214+'accesskey-pt-mycontris' => 'y', # don't translate or duplicate this message to other languages
 2215+'accesskey-pt-login' => 'o', # don't translate or duplicate this message to other languages
 2216+'accesskey-pt-anonlogin' => 'o', # don't translate or duplicate this message to other languages
 2217+'accesskey-pt-logout' => '', # don't translate or duplicate this message to other languages
 2218+'accesskey-ca-talk' => 't', # don't translate or duplicate this message to other languages
 2219+'accesskey-ca-edit' => 'e', # don't translate or duplicate this message to other languages
 2220+'accesskey-ca-addsection' => '+', # don't translate or duplicate this message to other languages
 2221+'accesskey-ca-viewsource' => 'e', # don't translate or duplicate this message to other languages
 2222+'accesskey-ca-history' => 'h', # don't translate or duplicate this message to other languages
 2223+'accesskey-ca-protect' => '=', # don't translate or duplicate this message to other languages
 2224+'accesskey-ca-delete' => 'd', # don't translate or duplicate this message to other languages
 2225+'accesskey-ca-undelete' => 'd', # don't translate or duplicate this message to other languages
 2226+'accesskey-ca-move' => 'm', # don't translate or duplicate this message to other languages
 2227+'accesskey-ca-watch' => 'w', # don't translate or duplicate this message to other languages
 2228+'accesskey-ca-unwatch' => 'w', # don't translate or duplicate this message to other languages
 2229+'accesskey-search' => 'f', # don't translate or duplicate this message to other languages
 2230+'accesskey-p-logo' => '', # don't translate or duplicate this message to other languages
 2231+'accesskey-n-mainpage' => 'z', # don't translate or duplicate this message to other languages
 2232+'accesskey-n-portal' => '', # don't translate or duplicate this message to other languages
 2233+'accesskey-n-currentevents' => '', # don't translate or duplicate this message to other languages
 2234+'accesskey-n-recentchanges' => 'r', # don't translate or duplicate this message to other languages
 2235+'accesskey-n-randompage' => 'x', # don't translate or duplicate this message to other languages
 2236+'accesskey-n-help' => '', # don't translate or duplicate this message to other languages
 2237+'accesskey-n-sitesupport' => '', # don't translate or duplicate this message to other languages
 2238+'accesskey-t-whatlinkshere' => 'j', # don't translate or duplicate this message to other languages
 2239+'accesskey-t-recentchangeslinked' => 'k', # don't translate or duplicate this message to other languages
 2240+'accesskey-feed-rss' => '', # don't translate or duplicate this message to other languages
 2241+'accesskey-feed-atom' => '', # don't translate or duplicate this message to other languages
 2242+'accesskey-t-contributions' => '', # don't translate or duplicate this message to other languages
 2243+'accesskey-t-emailuser' => '', # don't translate or duplicate this message to other languages
 2244+'accesskey-t-permalink' => '', # don't translate or duplicate this message to other languages
 2245+'accesskey-t-print' => 'p', # don't translate or duplicate this message to other languages
 2246+'accesskey-t-upload' => 'u', # don't translate or duplicate this message to other languages
 2247+'accesskey-t-specialpages' => 'q', # don't translate or duplicate this message to other languages
 2248+'accesskey-ca-nstab-main' => 'c', # don't translate or duplicate this message to other languages
 2249+'accesskey-ca-nstab-user' => 'c', # don't translate or duplicate this message to other languages
 2250+'accesskey-ca-nstab-media' => 'c', # don't translate or duplicate this message to other languages
 2251+'accesskey-ca-nstab-special' => '', # don't translate or duplicate this message to other languages
 2252+'accesskey-ca-nstab-project' => 'a', # don't translate or duplicate this message to other languages
 2253+'accesskey-ca-nstab-image' => 'c', # don't translate or duplicate this message to other languages
 2254+'accesskey-ca-nstab-mediawiki' => 'c', # don't translate or duplicate this message to other languages
 2255+'accesskey-ca-nstab-template' => 'c', # don't translate or duplicate this message to other languages
 2256+'accesskey-ca-nstab-help' => 'c', # don't translate or duplicate this message to other languages
 2257+'accesskey-ca-nstab-category' => 'c', # don't translate or duplicate this message to other languages
 2258+'accesskey-minoredit' => 'i', # don't translate or duplicate this message to other languages
 2259+'accesskey-save' => 's', # don't translate or duplicate this message to other languages
 2260+'accesskey-preview' => 'p', # don't translate or duplicate this message to other languages
 2261+'accesskey-diff' => 'v', # don't translate or duplicate this message to other languages
 2262+'accesskey-compareselectedversions' => 'v', # don't translate or duplicate this message to other languages
 2263+'accesskey-watch' => 'w', # don't translate or duplicate this message to other languages
22862264
22872265 # Tooltip help for the actions
2288 -'tooltip-pt-userpage' => 'My user page',
2289 -'tooltip-pt-anonuserpage' => "The user page for the ip you're editing as",
2290 -'tooltip-pt-mytalk' => 'My talk page',
2291 -'tooltip-pt-anontalk' => 'Discussion about edits from this ip address',
2292 -'tooltip-pt-preferences' => 'My preferences',
2293 -'tooltip-pt-watchlist' => "The list of pages you're monitoring for changes",
2294 -'tooltip-pt-mycontris' => 'List of my contributions',
2295 -'tooltip-pt-login' => 'You are encouraged to log in, it is not mandatory however.',
2296 -'tooltip-pt-anonlogin' => 'You are encouraged to log in, it is not mandatory however.',
2297 -'tooltip-pt-logout' => 'Log out',
2298 -'tooltip-ca-talk' => 'Discussion about the content page',
2299 -'tooltip-ca-edit' => 'You can edit this page. Please use the preview button before saving.',
2300 -'tooltip-ca-addsection' => 'Add a comment to this discussion.',
2301 -'tooltip-ca-viewsource' => 'This page is protected. You can view its source.',
2302 -'tooltip-ca-history' => 'Past versions of this page.',
2303 -'tooltip-ca-protect' => 'Protect this page',
2304 -'tooltip-ca-delete' => 'Delete this page',
2305 -'tooltip-ca-undelete' => 'Restore the edits done to this page before it was deleted',
2306 -'tooltip-ca-move' => 'Move this page',
2307 -'tooltip-ca-watch' => 'Add this page to your watchlist',
2308 -'tooltip-ca-unwatch' => 'Remove this page from your watchlist',
2309 -'tooltip-search' => 'Search {{SITENAME}}',
2310 -'tooltip-p-logo' => 'Main Page',
2311 -'tooltip-n-mainpage' => 'Visit the Main Page',
2312 -'tooltip-n-portal' => 'About the project, what you can do, where to find things',
2313 -'tooltip-n-currentevents' => 'Find background information on current events',
2314 -'tooltip-n-recentchanges' => 'The list of recent changes in the wiki.',
2315 -'tooltip-n-randompage' => 'Load a random page',
2316 -'tooltip-n-help' => 'The place to find out.',
2317 -'tooltip-n-sitesupport' => 'Support us',
2318 -'tooltip-t-whatlinkshere' => 'List of all wiki pages that link here',
2319 -'tooltip-t-recentchangeslinked' => 'Recent changes in pages linked from this page',
2320 -'tooltip-feed-rss' => 'RSS feed for this page',
2321 -'tooltip-feed-atom' => 'Atom feed for this page',
2322 -'tooltip-t-contributions' => 'View the list of contributions of this user',
2323 -'tooltip-t-emailuser' => 'Send a mail to this user',
2324 -'tooltip-t-upload' => 'Upload images or media files',
2325 -'tooltip-t-specialpages' => 'List of all special pages',
2326 -'tooltip-t-print' => 'Printable version of this page',
2327 -'tooltip-t-permalink' => 'Permanent link to this version of the page',
2328 -'tooltip-ca-nstab-main' => 'View the content page',
2329 -'tooltip-ca-nstab-user' => 'View the user page',
2330 -'tooltip-ca-nstab-media' => 'View the media page',
2331 -'tooltip-ca-nstab-special' => "This is a special page, you can't edit the page itself",
2332 -'tooltip-ca-nstab-project' => 'View the project page',
2333 -'tooltip-ca-nstab-image' => 'View the image page',
2334 -'tooltip-ca-nstab-mediawiki' => 'View the system message',
2335 -'tooltip-ca-nstab-template' => 'View the template',
2336 -'tooltip-ca-nstab-help' => 'View the help page',
2337 -'tooltip-ca-nstab-category' => 'View the category page',
2338 -'tooltip-minoredit' => 'Mark this as a minor edit',
2339 -'tooltip-save' => 'Save your changes',
2340 -'tooltip-preview' => 'Preview your changes, please use this before saving!',
2341 -'tooltip-diff' => 'Show which changes you made to the text.',
 2266+'tooltip-pt-userpage' => 'My user page',
 2267+'tooltip-pt-anonuserpage' => "The user page for the ip you're editing as",
 2268+'tooltip-pt-mytalk' => 'My talk page',
 2269+'tooltip-pt-anontalk' => 'Discussion about edits from this ip address',
 2270+'tooltip-pt-preferences' => 'My preferences',
 2271+'tooltip-pt-watchlist' => "The list of pages you're monitoring for changes",
 2272+'tooltip-pt-mycontris' => 'List of my contributions',
 2273+'tooltip-pt-login' => 'You are encouraged to log in, it is not mandatory however.',
 2274+'tooltip-pt-anonlogin' => 'You are encouraged to log in, it is not mandatory however.',
 2275+'tooltip-pt-logout' => 'Log out',
 2276+'tooltip-ca-talk' => 'Discussion about the content page',
 2277+'tooltip-ca-edit' => 'You can edit this page. Please use the preview button before saving.',
 2278+'tooltip-ca-addsection' => 'Add a comment to this discussion.',
 2279+'tooltip-ca-viewsource' => 'This page is protected. You can view its source.',
 2280+'tooltip-ca-history' => 'Past versions of this page.',
 2281+'tooltip-ca-protect' => 'Protect this page',
 2282+'tooltip-ca-delete' => 'Delete this page',
 2283+'tooltip-ca-undelete' => 'Restore the edits done to this page before it was deleted',
 2284+'tooltip-ca-move' => 'Move this page',
 2285+'tooltip-ca-watch' => 'Add this page to your watchlist',
 2286+'tooltip-ca-unwatch' => 'Remove this page from your watchlist',
 2287+'tooltip-search' => 'Search {{SITENAME}}',
 2288+'tooltip-p-logo' => 'Main Page',
 2289+'tooltip-n-mainpage' => 'Visit the Main Page',
 2290+'tooltip-n-portal' => 'About the project, what you can do, where to find things',
 2291+'tooltip-n-currentevents' => 'Find background information on current events',
 2292+'tooltip-n-recentchanges' => 'The list of recent changes in the wiki.',
 2293+'tooltip-n-randompage' => 'Load a random page',
 2294+'tooltip-n-help' => 'The place to find out.',
 2295+'tooltip-n-sitesupport' => 'Support us',
 2296+'tooltip-t-whatlinkshere' => 'List of all wiki pages that link here',
 2297+'tooltip-t-recentchangeslinked' => 'Recent changes in pages linked from this page',
 2298+'tooltip-feed-rss' => 'RSS feed for this page',
 2299+'tooltip-feed-atom' => 'Atom feed for this page',
 2300+'tooltip-t-contributions' => 'View the list of contributions of this user',
 2301+'tooltip-t-emailuser' => 'Send a mail to this user',
 2302+'tooltip-t-upload' => 'Upload images or media files',
 2303+'tooltip-t-specialpages' => 'List of all special pages',
 2304+'tooltip-t-print' => 'Printable version of this page',
 2305+'tooltip-t-permalink' => 'Permanent link to this version of the page',
 2306+'tooltip-ca-nstab-main' => 'View the content page',
 2307+'tooltip-ca-nstab-user' => 'View the user page',
 2308+'tooltip-ca-nstab-media' => 'View the media page',
 2309+'tooltip-ca-nstab-special' => "This is a special page, you can't edit the page itself",
 2310+'tooltip-ca-nstab-project' => 'View the project page',
 2311+'tooltip-ca-nstab-image' => 'View the image page',
 2312+'tooltip-ca-nstab-mediawiki' => 'View the system message',
 2313+'tooltip-ca-nstab-template' => 'View the template',
 2314+'tooltip-ca-nstab-help' => 'View the help page',
 2315+'tooltip-ca-nstab-category' => 'View the category page',
 2316+'tooltip-minoredit' => 'Mark this as a minor edit',
 2317+'tooltip-save' => 'Save your changes',
 2318+'tooltip-preview' => 'Preview your changes, please use this before saving!',
 2319+'tooltip-diff' => 'Show which changes you made to the text.',
23422320 'tooltip-compareselectedversions' => 'See the differences between the two selected versions of this page.',
2343 -'tooltip-watch' => 'Add this page to your watchlist',
2344 -'tooltip-recreate' => 'Recreate the page despite it has been deleted',
 2321+'tooltip-watch' => 'Add this page to your watchlist',
 2322+'tooltip-recreate' => 'Recreate the page despite it has been deleted',
23452323
2346 -# stylesheets
2347 -'common.css' => '/** CSS placed here will be applied to all skins */',
 2324+# Stylesheets
 2325+'common.css' => '/** CSS placed here will be applied to all skins */',
23482326 'monobook.css' => '/* CSS placed here will affect users of the Monobook skin */',
23492327
23502328 # Scripts
2351 -'common.js' => '/* Any JavaScript here will be loaded for all users on every page load. */',
 2329+'common.js' => '/* Any JavaScript here will be loaded for all users on every page load. */',
23522330 'monobook.js' => '/* Deprecated; use [[MediaWiki:common.js]] */',
23532331
23542332 # Metadata
2355 -'nodublincore' => 'Dublin Core RDF metadata disabled for this server.',
 2333+'nodublincore' => 'Dublin Core RDF metadata disabled for this server.',
23562334 'nocreativecommons' => 'Creative Commons RDF metadata disabled for this server.',
2357 -'notacceptable' => 'The wiki server can\'t provide data in a format your client can read.',
 2335+'notacceptable' => "The wiki server can't provide data in a format your client can read.",
23582336
23592337 # Attribution
 2338+'anonymous' => 'Anonymous user(s) of {{SITENAME}}',
 2339+'siteuser' => '{{SITENAME}} user $1',
 2340+'lastmodifiedatby' => 'This page was last modified $2, $1 by $3.', # $1 date, $2 time, $3 user
 2341+'and' => 'and',
 2342+'othercontribs' => 'Based on work by $1.',
 2343+'others' => 'others',
 2344+'siteusers' => '{{SITENAME}} user(s) $1',
 2345+'creditspage' => 'Page credits',
 2346+'nocredits' => 'There is no credits info available for this page.',
23602347
2361 -'anonymous' => 'Anonymous user(s) of {{SITENAME}}',
2362 -'siteuser' => '{{SITENAME}} user $1',
2363 -'lastmodifiedatby' => 'This page was last modified $2, $1 by $3.', // $1 date, $2 time. $3 user
2364 -'and' => 'and',
2365 -'othercontribs' => 'Based on work by $1.',
2366 -'others' => 'others',
2367 -'siteusers' => '{{SITENAME}} user(s) $1',
2368 -'creditspage' => 'Page credits',
2369 -'nocredits' => 'There is no credits info available for this page.',
2370 -
23712348 # Spam protection
 2349+'spamprotectiontitle' => 'Spam protection filter',
 2350+'spamprotectiontext' => 'The page you wanted to save was blocked by the spam filter. This is probably caused by a link to an external site.',
 2351+'spamprotectionmatch' => 'The following text is what triggered our spam filter: $1',
 2352+'subcategorycount' => 'There {{PLURAL:$1|is one subcategory|are $1 subcategories}} to this category.',
 2353+'categoryarticlecount' => 'There {{PLURAL:$1|is one article|are $1 articles}} in this category.',
 2354+'category-media-count' => 'There {{PLURAL:$1|is one file|are $1 files}} in this category.',
 2355+'listingcontinuesabbrev' => ' cont.',
 2356+'spambot_username' => 'MediaWiki spam cleanup',
 2357+'spam_reverting' => 'Reverting to last version not containing links to $1',
 2358+'spam_blanking' => 'All revisions contained links to $1, blanking',
23722359
2373 -'spamprotectiontitle' => 'Spam protection filter',
2374 -'spamprotectiontext' => 'The page you wanted to save was blocked by the spam filter. This is probably caused by a link to an external site.',
2375 -'spamprotectionmatch' => 'The following text is what triggered our spam filter: $1',
2376 -'subcategorycount' => "There {{PLURAL:$1|is one subcategory|are $1 subcategories}} to this category.",
2377 -'categoryarticlecount' => "There {{PLURAL:$1|is one article|are $1 articles}} in this category.",
2378 -'category-media-count' => "There {{PLURAL:$1|is one file|are $1 files}} in this category.",
2379 -'listingcontinuesabbrev' => " cont.",
2380 -'spambot_username' => 'MediaWiki spam cleanup',
2381 -'spam_reverting' => 'Reverting to last version not containing links to $1',
2382 -'spam_blanking' => 'All revisions contained links to $1, blanking',
2383 -
23842360 # Info page
2385 -'infosubtitle' => 'Information for page',
2386 -'numedits' => 'Number of edits (article): $1',
2387 -'numtalkedits' => 'Number of edits (discussion page): $1',
2388 -'numwatchers' => 'Number of watchers: $1',
2389 -'numauthors' => 'Number of distinct authors (article): $1',
 2361+'infosubtitle' => 'Information for page',
 2362+'numedits' => 'Number of edits (article): $1',
 2363+'numtalkedits' => 'Number of edits (discussion page): $1',
 2364+'numwatchers' => 'Number of watchers: $1',
 2365+'numauthors' => 'Number of distinct authors (article): $1',
23902366 'numtalkauthors' => 'Number of distinct authors (discussion page): $1',
23912367
23922368 # Math options
2393 -'mw_math_png' => 'Always render PNG',
 2369+'mw_math_png' => 'Always render PNG',
23942370 'mw_math_simple' => 'HTML if very simple or else PNG',
2395 -'mw_math_html' => 'HTML if possible or else PNG',
 2371+'mw_math_html' => 'HTML if possible or else PNG',
23962372 'mw_math_source' => 'Leave it as TeX (for text browsers)',
23972373 'mw_math_modern' => 'Recommended for modern browsers',
23982374 'mw_math_mathml' => 'MathML if possible (experimental)',
23992375
24002376 # Patrolling
2401 -'markaspatrolleddiff' => "Mark as patrolled",
2402 -'markaspatrolledlink' => "[$1]",
2403 -'markaspatrolledtext' => "Mark this article as patrolled",
2404 -'markedaspatrolled' => "Marked as patrolled",
2405 -'markedaspatrolledtext' => "The selected revision has been marked as patrolled.",
2406 -'rcpatroldisabled' => "Recent Changes Patrol disabled",
2407 -'rcpatroldisabledtext' => "The Recent Changes Patrol feature is currently disabled.",
2408 -'markedaspatrollederror' => "Cannot mark as patrolled",
2409 -'markedaspatrollederrortext' => "You need to specify a revision to mark as patrolled.",
 2377+'markaspatrolleddiff' => 'Mark as patrolled',
 2378+'markaspatrolledlink' => '[$1]', # don't translate or duplicate this message to other languages
 2379+'markaspatrolledtext' => 'Mark this article as patrolled',
 2380+'markedaspatrolled' => 'Marked as patrolled',
 2381+'markedaspatrolledtext' => 'The selected revision has been marked as patrolled.',
 2382+'rcpatroldisabled' => 'Recent Changes Patrol disabled',
 2383+'rcpatroldisabledtext' => 'The Recent Changes Patrol feature is currently disabled.',
 2384+'markedaspatrollederror' => 'Cannot mark as patrolled',
 2385+'markedaspatrollederrortext' => 'You need to specify a revision to mark as patrolled.',
24102386 'markedaspatrollederror-noautopatrol' => 'You are not allowed to mark your own changes as patrolled.',
24112387
24122388 # Patrol log
2413 -'patrol-log-page' => 'Patrol log',
2414 -'patrol-log-header' => '',
2415 -'patrol-log-line' => 'marked $1 of $2 patrolled $3',
2416 -'patrol-log-auto' => '(automatic)',
2417 -'patrol-log-diff' => 'r$1',
 2389+'patrol-log-page' => 'Patrol log',
 2390+'patrol-log-header' => '', # don't translate or duplicate this message to other languages
 2391+'patrol-log-line' => 'marked $1 of $2 patrolled $3',
 2392+'patrol-log-auto' => '(automatic)',
 2393+'patrol-log-diff' => 'r$1',
24182394
2419 -# image deletion
 2395+# Image deletion
24202396 'deletedrevision' => 'Deleted old revision $1.',
24212397
2422 -# browsing diffs
 2398+# Browsing diffs
24232399 'previousdiff' => '← Previous diff',
2424 -'nextdiff' => 'Next diff →',
 2400+'nextdiff' => 'Next diff →',
24252401
2426 -# media-info
2427 -'mediawarning' => "'''Warning''': This file may contain malicious code, by executing it your system may be compromised.<hr />",
2428 -'imagemaxsize' => 'Limit images on image description pages to:',
2429 -'thumbsize' => 'Thumbnail size:',
2430 -'widthheight' => '$1×$2',
2431 -'file-info' => '(file size: $1, MIME type: $2)',
2432 -'file-info-size' => '($1 × $2 pixel, file size: $3, MIME type: $4)',
2433 -'file-nohires' => '<small>No higher resolution available.</small>',
2434 -'file-svg' => '<small>This is a lossless scalable vector image. Base size: $1 × $2 pixels.</small>',
2435 -'show-big-image' => 'Full resolution',
2436 -'show-big-image-thumb' => '<small>Size of this preview: $1 × $2 pixels</small>',
 2402+# Media information
 2403+'mediawarning' => "'''Warning''': This file may contain malicious code, by executing it your system may be compromised.<hr />",
 2404+'imagemaxsize' => 'Limit images on image description pages to:',
 2405+'thumbsize' => 'Thumbnail size:',
 2406+'widthheight' => '$1×$2', # only translate this message to other languages if you have to change it
 2407+'file-info' => '(file size: $1, MIME type: $2)',
 2408+'file-info-size' => '($1 × $2 pixel, file size: $3, MIME type: $4)',
 2409+'file-nohires' => '<small>No higher resolution available.</small>',
 2410+'file-svg' => '<small>This is a lossless scalable vector image. Base size: $1 × $2 pixels.</small>',
 2411+'show-big-image' => 'Full resolution',
 2412+'show-big-image-thumb' => '<small>Size of this preview: $1 × $2 pixels</small>',
24372413
2438 -'newimages' => 'Gallery of new files',
2439 -'newimages-summary' => '',
2440 -'showhidebots' => '($1 bots)',
2441 -'noimages' => 'Nothing to see.',
 2414+'newimages' => 'Gallery of new files',
 2415+'newimages-summary' => '', # only translate this message to other languages if you have to change it
 2416+'showhidebots' => '($1 bots)',
 2417+'noimages' => 'Nothing to see.',
24422418
2443 -# short names for language variants used for language conversion links.
2444 -# to disable showing a particular link, set it to 'disable', e.g.
2445 -# 'variantname-zh-sg' => 'disable',
2446 -'variantname-zh-cn' => 'cn',
2447 -'variantname-zh-tw' => 'tw',
2448 -'variantname-zh-hk' => 'hk',
2449 -'variantname-zh-sg' => 'sg',
2450 -'variantname-zh' => 'zh',
2451 -# variants for Serbian language
2452 -'variantname-sr-ec' => 'sr-ec',
2453 -'variantname-sr-el' => 'sr-el',
2454 -'variantname-sr-jc' => 'sr-jc',
2455 -'variantname-sr-jl' => 'sr-jl',
2456 -'variantname-sr' => 'sr',
2457 -# variants for Kazakh language
2458 -'variantname-kk-tr' => 'kk-tr',
2459 -'variantname-kk-kz' => 'kk-kz',
2460 -'variantname-kk-cn' => 'kk-cn',
2461 -'variantname-kk' => 'kk',
 2419+/*
 2420+Short names for language variants used for language conversion links.
 2421+To disable showing a particular link, set it to 'disable', e.g.
 2422+'variantname-zh-sg' => 'disable',
 2423+Variants for Chinese language
 2424+*/
 2425+'variantname-zh-cn' => 'cn', # only translate this message to other languages if you have to change it
 2426+'variantname-zh-tw' => 'tw', # only translate this message to other languages if you have to change it
 2427+'variantname-zh-hk' => 'hk', # only translate this message to other languages if you have to change it
 2428+'variantname-zh-sg' => 'sg', # only translate this message to other languages if you have to change it
 2429+'variantname-zh' => 'zh', # only translate this message to other languages if you have to change it
24622430
 2431+# Variants for Serbian language
 2432+'variantname-sr-ec' => 'sr-ec', # only translate this message to other languages if you have to change it
 2433+'variantname-sr-el' => 'sr-el', # only translate this message to other languages if you have to change it
 2434+'variantname-sr-jc' => 'sr-jc', # only translate this message to other languages if you have to change it
 2435+'variantname-sr-jl' => 'sr-jl', # only translate this message to other languages if you have to change it
 2436+'variantname-sr' => 'sr', # only translate this message to other languages if you have to change it
 2437+
 2438+# Variants for Kazakh language
 2439+'variantname-kk-tr' => 'kk-tr', # only translate this message to other languages if you have to change it
 2440+'variantname-kk-kz' => 'kk-kz', # only translate this message to other languages if you have to change it
 2441+'variantname-kk-cn' => 'kk-cn', # only translate this message to other languages if you have to change it
 2442+'variantname-kk' => 'kk', # only translate this message to other languages if you have to change it
 2443+
24632444 'passwordtooshort' => 'Your password is invalid or too short. It must have at least $1 characters and be different from your username.',
24642445
24652446 # Metadata
2466 -'metadata' => 'Metadata',
2467 -'metadata-help' => 'This file contains additional information, probably added from the digital camera or scanner used to create or digitize it. If the file has been modified from its original state, some details may not fully reflect the modified image.',
2468 -'metadata-expand' => 'Show extended details',
 2447+'metadata' => 'Metadata',
 2448+'metadata-help' => 'This file contains additional information, probably added from the digital camera or scanner used to create or digitize it. If the file has been modified from its original state, some details may not fully reflect the modified image.',
 2449+'metadata-expand' => 'Show extended details',
24692450 'metadata-collapse' => 'Hide extended details',
2470 -'metadata-fields' => 'EXIF metadata fields listed in this message will
 2451+'metadata-fields' => 'EXIF metadata fields listed in this message will
24712452 be included on image page display when the metadata table
24722453 is collapsed. Others will be hidden by default.
24732454 * make
@@ -2476,160 +2457,158 @@
24772458 * fnumber
24782459 * focallength',
24792460
2480 -# Exif tags
2481 -'exif-imagewidth' =>'Width',
2482 -'exif-imagelength' =>'Height',
2483 -'exif-bitspersample' =>'Bits per component',
2484 -'exif-compression' =>'Compression scheme',
2485 -'exif-photometricinterpretation' =>'Pixel composition',
2486 -'exif-orientation' =>'Orientation',
2487 -'exif-samplesperpixel' =>'Number of components',
2488 -'exif-planarconfiguration' =>'Data arrangement',
2489 -'exif-ycbcrsubsampling' =>'Subsampling ratio of Y to C',
2490 -'exif-ycbcrpositioning' =>'Y and C positioning',
2491 -'exif-xresolution' =>'Horizontal resolution',
2492 -'exif-yresolution' =>'Vertical resolution',
2493 -'exif-resolutionunit' =>'Unit of X and Y resolution',
2494 -'exif-stripoffsets' =>'Image data location',
2495 -'exif-rowsperstrip' =>'Number of rows per strip',
2496 -'exif-stripbytecounts' =>'Bytes per compressed strip',
2497 -'exif-jpeginterchangeformat' =>'Offset to JPEG SOI',
2498 -'exif-jpeginterchangeformatlength' =>'Bytes of JPEG data',
2499 -'exif-transferfunction' =>'Transfer function',
2500 -'exif-whitepoint' =>'White point chromaticity',
2501 -'exif-primarychromaticities' =>'Chromaticities of primarities',
2502 -'exif-ycbcrcoefficients' =>'Color space transformation matrix coefficients',
2503 -'exif-referenceblackwhite' =>'Pair of black and white reference values',
2504 -'exif-datetime' =>'File change date and time',
2505 -'exif-imagedescription' =>'Image title',
2506 -'exif-make' =>'Camera manufacturer',
2507 -'exif-model' =>'Camera model',
2508 -'exif-software' =>'Software used',
2509 -'exif-artist' =>'Author',
2510 -'exif-copyright' =>'Copyright holder',
2511 -'exif-exifversion' =>'Exif version',
2512 -'exif-flashpixversion' =>'Supported Flashpix version',
2513 -'exif-colorspace' =>'Color space',
2514 -'exif-componentsconfiguration' =>'Meaning of each component',
2515 -'exif-compressedbitsperpixel' =>'Image compression mode',
2516 -'exif-pixelydimension' =>'Valid image width',
2517 -'exif-pixelxdimension' =>'Valid image height',
2518 -'exif-makernote' =>'Manufacturer notes',
2519 -'exif-usercomment' =>'User comments',
2520 -'exif-relatedsoundfile' =>'Related audio file',
2521 -'exif-datetimeoriginal' =>'Date and time of data generation',
2522 -'exif-datetimedigitized' =>'Date and time of digitizing',
2523 -'exif-subsectime' =>'DateTime subseconds',
2524 -'exif-subsectimeoriginal' =>'DateTimeOriginal subseconds',
2525 -'exif-subsectimedigitized' =>'DateTimeDigitized subseconds',
2526 -'exif-exposuretime' =>'Exposure time',
2527 -'exif-exposuretime-format' => '$1 sec ($2)',
2528 -'exif-fnumber' =>'F Number',
2529 -'exif-fnumber-format' =>'f/$1',
2530 -'exif-exposureprogram' =>'Exposure Program',
2531 -'exif-spectralsensitivity' =>'Spectral sensitivity',
2532 -'exif-isospeedratings' =>'ISO speed rating',
2533 -'exif-oecf' =>'Optoelectronic conversion factor',
2534 -'exif-shutterspeedvalue' =>'Shutter speed',
2535 -'exif-aperturevalue' =>'Aperture',
2536 -'exif-brightnessvalue' =>'Brightness',
2537 -'exif-exposurebiasvalue' =>'Exposure bias',
2538 -'exif-maxaperturevalue' =>'Maximum land aperture',
2539 -'exif-subjectdistance' =>'Subject distance',
2540 -'exif-meteringmode' =>'Metering mode',
2541 -'exif-lightsource' =>'Light source',
2542 -'exif-flash' =>'Flash',
2543 -'exif-focallength' =>'Lens focal length',
2544 -'exif-focallength-format' =>'$1 mm',
2545 -'exif-subjectarea' =>'Subject area',
2546 -'exif-flashenergy' =>'Flash energy',
2547 -'exif-spatialfrequencyresponse' =>'Spatial frequency response',
2548 -'exif-focalplanexresolution' =>'Focal plane X resolution',
2549 -'exif-focalplaneyresolution' =>'Focal plane Y resolution',
2550 -'exif-focalplaneresolutionunit' =>'Focal plane resolution unit',
2551 -'exif-subjectlocation' =>'Subject location',
2552 -'exif-exposureindex' =>'Exposure index',
2553 -'exif-sensingmethod' =>'Sensing method',
2554 -'exif-filesource' =>'File source',
2555 -'exif-scenetype' =>'Scene type',
2556 -'exif-cfapattern' =>'CFA pattern',
2557 -'exif-customrendered' =>'Custom image processing',
2558 -'exif-exposuremode' =>'Exposure mode',
2559 -'exif-whitebalance' =>'White Balance',
2560 -'exif-digitalzoomratio' =>'Digital zoom ratio',
2561 -'exif-focallengthin35mmfilm' =>'Focal length in 35 mm film',
2562 -'exif-scenecapturetype' =>'Scene capture type',
2563 -'exif-gaincontrol' =>'Scene control',
2564 -'exif-contrast' =>'Contrast',
2565 -'exif-saturation' =>'Saturation',
2566 -'exif-sharpness' =>'Sharpness',
2567 -'exif-devicesettingdescription' =>'Device settings description',
2568 -'exif-subjectdistancerange' =>'Subject distance range',
2569 -'exif-imageuniqueid' =>'Unique image ID',
2570 -'exif-gpsversionid' =>'GPS tag version',
2571 -'exif-gpslatituderef' =>'North or South Latitude',
2572 -'exif-gpslatitude' =>'Latitude',
2573 -'exif-gpslongituderef' =>'East or West Longitude',
2574 -'exif-gpslongitude' =>'Longitude',
2575 -'exif-gpsaltituderef' =>'Altitude reference',
2576 -'exif-gpsaltitude' =>'Altitude',
2577 -'exif-gpstimestamp' =>'GPS time (atomic clock)',
2578 -'exif-gpssatellites' =>'Satellites used for measurement',
2579 -'exif-gpsstatus' =>'Receiver status',
2580 -'exif-gpsmeasuremode' =>'Measurement mode',
2581 -'exif-gpsdop' =>'Measurement precision',
2582 -'exif-gpsspeedref' =>'Speed unit',
2583 -'exif-gpsspeed' =>'Speed of GPS receiver',
2584 -'exif-gpstrackref' =>'Reference for direction of movement',
2585 -'exif-gpstrack' =>'Direction of movement',
2586 -'exif-gpsimgdirectionref' =>'Reference for direction of image',
2587 -'exif-gpsimgdirection' =>'Direction of image',
2588 -'exif-gpsmapdatum' =>'Geodetic survey data used',
2589 -'exif-gpsdestlatituderef' =>'Reference for latitude of destination',
2590 -'exif-gpsdestlatitude' =>'Latitude destination',
2591 -'exif-gpsdestlongituderef' =>'Reference for longitude of destination',
2592 -'exif-gpsdestlongitude' =>'Longitude of destination',
2593 -'exif-gpsdestbearingref' =>'Reference for bearing of destination',
2594 -'exif-gpsdestbearing' =>'Bearing of destination',
2595 -'exif-gpsdestdistanceref' =>'Reference for distance to destination',
2596 -'exif-gpsdestdistance' =>'Distance to destination',
2597 -'exif-gpsprocessingmethod' =>'Name of GPS processing method',
2598 -'exif-gpsareainformation' =>'Name of GPS area',
2599 -'exif-gpsdatestamp' =>'GPS date',
2600 -'exif-gpsdifferential' =>'GPS differential correction',
 2461+# EXIF tags
 2462+'exif-imagewidth' => 'Width',
 2463+'exif-imagelength' => 'Height',
 2464+'exif-bitspersample' => 'Bits per component',
 2465+'exif-compression' => 'Compression scheme',
 2466+'exif-photometricinterpretation' => 'Pixel composition',
 2467+'exif-orientation' => 'Orientation',
 2468+'exif-samplesperpixel' => 'Number of components',
 2469+'exif-planarconfiguration' => 'Data arrangement',
 2470+'exif-ycbcrsubsampling' => 'Subsampling ratio of Y to C',
 2471+'exif-ycbcrpositioning' => 'Y and C positioning',
 2472+'exif-xresolution' => 'Horizontal resolution',
 2473+'exif-yresolution' => 'Vertical resolution',
 2474+'exif-resolutionunit' => 'Unit of X and Y resolution',
 2475+'exif-stripoffsets' => 'Image data location',
 2476+'exif-rowsperstrip' => 'Number of rows per strip',
 2477+'exif-stripbytecounts' => 'Bytes per compressed strip',
 2478+'exif-jpeginterchangeformat' => 'Offset to JPEG SOI',
 2479+'exif-jpeginterchangeformatlength' => 'Bytes of JPEG data',
 2480+'exif-transferfunction' => 'Transfer function',
 2481+'exif-whitepoint' => 'White point chromaticity',
 2482+'exif-primarychromaticities' => 'Chromaticities of primarities',
 2483+'exif-ycbcrcoefficients' => 'Color space transformation matrix coefficients',
 2484+'exif-referenceblackwhite' => 'Pair of black and white reference values',
 2485+'exif-datetime' => 'File change date and time',
 2486+'exif-imagedescription' => 'Image title',
 2487+'exif-make' => 'Camera manufacturer',
 2488+'exif-model' => 'Camera model',
 2489+'exif-software' => 'Software used',
 2490+'exif-artist' => 'Author',
 2491+'exif-copyright' => 'Copyright holder',
 2492+'exif-exifversion' => 'Exif version',
 2493+'exif-flashpixversion' => 'Supported Flashpix version',
 2494+'exif-colorspace' => 'Color space',
 2495+'exif-componentsconfiguration' => 'Meaning of each component',
 2496+'exif-compressedbitsperpixel' => 'Image compression mode',
 2497+'exif-pixelydimension' => 'Valid image width',
 2498+'exif-pixelxdimension' => 'Valid image height',
 2499+'exif-makernote' => 'Manufacturer notes',
 2500+'exif-usercomment' => 'User comments',
 2501+'exif-relatedsoundfile' => 'Related audio file',
 2502+'exif-datetimeoriginal' => 'Date and time of data generation',
 2503+'exif-datetimedigitized' => 'Date and time of digitizing',
 2504+'exif-subsectime' => 'DateTime subseconds',
 2505+'exif-subsectimeoriginal' => 'DateTimeOriginal subseconds',
 2506+'exif-subsectimedigitized' => 'DateTimeDigitized subseconds',
 2507+'exif-exposuretime' => 'Exposure time',
 2508+'exif-exposuretime-format' => '$1 sec ($2)',
 2509+'exif-fnumber' => 'F Number',
 2510+'exif-fnumber-format' => 'f/$1',
 2511+'exif-exposureprogram' => 'Exposure Program',
 2512+'exif-spectralsensitivity' => 'Spectral sensitivity',
 2513+'exif-isospeedratings' => 'ISO speed rating',
 2514+'exif-oecf' => 'Optoelectronic conversion factor',
 2515+'exif-shutterspeedvalue' => 'Shutter speed',
 2516+'exif-aperturevalue' => 'Aperture',
 2517+'exif-brightnessvalue' => 'Brightness',
 2518+'exif-exposurebiasvalue' => 'Exposure bias',
 2519+'exif-maxaperturevalue' => 'Maximum land aperture',
 2520+'exif-subjectdistance' => 'Subject distance',
 2521+'exif-meteringmode' => 'Metering mode',
 2522+'exif-lightsource' => 'Light source',
 2523+'exif-flash' => 'Flash',
 2524+'exif-focallength' => 'Lens focal length',
 2525+'exif-focallength-format' => '$1 mm',
 2526+'exif-subjectarea' => 'Subject area',
 2527+'exif-flashenergy' => 'Flash energy',
 2528+'exif-spatialfrequencyresponse' => 'Spatial frequency response',
 2529+'exif-focalplanexresolution' => 'Focal plane X resolution',
 2530+'exif-focalplaneyresolution' => 'Focal plane Y resolution',
 2531+'exif-focalplaneresolutionunit' => 'Focal plane resolution unit',
 2532+'exif-subjectlocation' => 'Subject location',
 2533+'exif-exposureindex' => 'Exposure index',
 2534+'exif-sensingmethod' => 'Sensing method',
 2535+'exif-filesource' => 'File source',
 2536+'exif-scenetype' => 'Scene type',
 2537+'exif-cfapattern' => 'CFA pattern',
 2538+'exif-customrendered' => 'Custom image processing',
 2539+'exif-exposuremode' => 'Exposure mode',
 2540+'exif-whitebalance' => 'White Balance',
 2541+'exif-digitalzoomratio' => 'Digital zoom ratio',
 2542+'exif-focallengthin35mmfilm' => 'Focal length in 35 mm film',
 2543+'exif-scenecapturetype' => 'Scene capture type',
 2544+'exif-gaincontrol' => 'Scene control',
 2545+'exif-contrast' => 'Contrast',
 2546+'exif-saturation' => 'Saturation',
 2547+'exif-sharpness' => 'Sharpness',
 2548+'exif-devicesettingdescription' => 'Device settings description',
 2549+'exif-subjectdistancerange' => 'Subject distance range',
 2550+'exif-imageuniqueid' => 'Unique image ID',
 2551+'exif-gpsversionid' => 'GPS tag version',
 2552+'exif-gpslatituderef' => 'North or South Latitude',
 2553+'exif-gpslatitude' => 'Latitude',
 2554+'exif-gpslongituderef' => 'East or West Longitude',
 2555+'exif-gpslongitude' => 'Longitude',
 2556+'exif-gpsaltituderef' => 'Altitude reference',
 2557+'exif-gpsaltitude' => 'Altitude',
 2558+'exif-gpstimestamp' => 'GPS time (atomic clock)',
 2559+'exif-gpssatellites' => 'Satellites used for measurement',
 2560+'exif-gpsstatus' => 'Receiver status',
 2561+'exif-gpsmeasuremode' => 'Measurement mode',
 2562+'exif-gpsdop' => 'Measurement precision',
 2563+'exif-gpsspeedref' => 'Speed unit',
 2564+'exif-gpsspeed' => 'Speed of GPS receiver',
 2565+'exif-gpstrackref' => 'Reference for direction of movement',
 2566+'exif-gpstrack' => 'Direction of movement',
 2567+'exif-gpsimgdirectionref' => 'Reference for direction of image',
 2568+'exif-gpsimgdirection' => 'Direction of image',
 2569+'exif-gpsmapdatum' => 'Geodetic survey data used',
 2570+'exif-gpsdestlatituderef' => 'Reference for latitude of destination',
 2571+'exif-gpsdestlatitude' => 'Latitude destination',
 2572+'exif-gpsdestlongituderef' => 'Reference for longitude of destination',
 2573+'exif-gpsdestlongitude' => 'Longitude of destination',
 2574+'exif-gpsdestbearingref' => 'Reference for bearing of destination',
 2575+'exif-gpsdestbearing' => 'Bearing of destination',
 2576+'exif-gpsdestdistanceref' => 'Reference for distance to destination',
 2577+'exif-gpsdestdistance' => 'Distance to destination',
 2578+'exif-gpsprocessingmethod' => 'Name of GPS processing method',
 2579+'exif-gpsareainformation' => 'Name of GPS area',
 2580+'exif-gpsdatestamp' => 'GPS date',
 2581+'exif-gpsdifferential' => 'GPS differential correction',
26012582
26022583 # Make & model, can be wikified in order to link to the camera and model name
 2584+'exif-make-value' => '$1', # don't translate or duplicate this message to other languages
 2585+'exif-model-value' => '$1', # don't translate or duplicate this message to other languages
 2586+'exif-software-value' => '$1', # don't translate or duplicate this message to other languages
26032587
2604 -'exif-make-value' => '$1',
2605 -'exif-model-value' =>'$1',
2606 -'exif-software-value' => '$1',
2607 -
2608 -# Exif attributes
2609 -
 2588+# EXIF attributes
26102589 'exif-compression-1' => 'Uncompressed',
26112590 'exif-compression-6' => 'JPEG',
26122591
2613 -'exif-unknowndate' => 'Unknown date',
2614 -
26152592 'exif-photometricinterpretation-2' => 'RGB',
26162593 'exif-photometricinterpretation-6' => 'YCbCr',
26172594
2618 -'exif-orientation-1' => 'Normal', // 0th row: top; 0th column: left
2619 -'exif-orientation-2' => 'Flipped horizontally', // 0th row: top; 0th column: right
2620 -'exif-orientation-3' => 'Rotated 180°', // 0th row: bottom; 0th column: right
2621 -'exif-orientation-4' => 'Flipped vertically', // 0th row: bottom; 0th column: left
2622 -'exif-orientation-5' => 'Rotated 90° CCW and flipped vertically', // 0th row: left; 0th column: top
2623 -'exif-orientation-6' => 'Rotated 90° CW', // 0th row: right; 0th column: top
2624 -'exif-orientation-7' => 'Rotated 90° CW and flipped vertically', // 0th row: right; 0th column: bottom
2625 -'exif-orientation-8' => 'Rotated 90° CCW', // 0th row: left; 0th column: bottom
 2595+'exif-unknowndate' => 'Unknown date',
26262596
 2597+'exif-orientation-1' => 'Normal', # 0th row: top; 0th column: left
 2598+'exif-orientation-2' => 'Flipped horizontally', # 0th row: top; 0th column: right
 2599+'exif-orientation-3' => 'Rotated 180°', # 0th row: bottom; 0th column: right
 2600+'exif-orientation-4' => 'Flipped vertically', # 0th row: bottom; 0th column: left
 2601+'exif-orientation-5' => 'Rotated 90° CCW and flipped vertically', # 0th row: left; 0th column: top
 2602+'exif-orientation-6' => 'Rotated 90° CW', # 0th row: right; 0th column: top
 2603+'exif-orientation-7' => 'Rotated 90° CW and flipped vertically', # 0th row: right; 0th column: bottom
 2604+'exif-orientation-8' => 'Rotated 90° CCW', # 0th row: left; 0th column: bottom
 2605+
26272606 'exif-planarconfiguration-1' => 'chunky format',
26282607 'exif-planarconfiguration-2' => 'planar format',
26292608
26302609 'exif-xyresolution-i' => '$1 dpi',
26312610 'exif-xyresolution-c' => '$1 dpc',
26322611
2633 -'exif-colorspace-1' => 'sRGB',
 2612+'exif-colorspace-1' => 'sRGB',
26342613 'exif-colorspace-ffff.h' => 'FFFF.H',
26352614
26362615 'exif-componentsconfiguration-0' => 'does not exist',
@@ -2652,35 +2631,35 @@
26532632
26542633 'exif-subjectdistance-value' => '$1 metres',
26552634
2656 -'exif-meteringmode-0' => 'Unknown',
2657 -'exif-meteringmode-1' => 'Average',
2658 -'exif-meteringmode-2' => 'CenterWeightedAverage',
2659 -'exif-meteringmode-3' => 'Spot',
2660 -'exif-meteringmode-4' => 'MultiSpot',
2661 -'exif-meteringmode-5' => 'Pattern',
2662 -'exif-meteringmode-6' => 'Partial',
 2635+'exif-meteringmode-0' => 'Unknown',
 2636+'exif-meteringmode-1' => 'Average',
 2637+'exif-meteringmode-2' => 'CenterWeightedAverage',
 2638+'exif-meteringmode-3' => 'Spot',
 2639+'exif-meteringmode-4' => 'MultiSpot',
 2640+'exif-meteringmode-5' => 'Pattern',
 2641+'exif-meteringmode-6' => 'Partial',
26632642 'exif-meteringmode-255' => 'Other',
26642643
2665 -'exif-lightsource-0' => 'Unknown',
2666 -'exif-lightsource-1' => 'Daylight',
2667 -'exif-lightsource-2' => 'Fluorescent',
2668 -'exif-lightsource-3' => 'Tungsten (incandescent light)',
2669 -'exif-lightsource-4' => 'Flash',
2670 -'exif-lightsource-9' => 'Fine weather',
2671 -'exif-lightsource-10' => 'Cloudy weather',
2672 -'exif-lightsource-11' => 'Shade',
2673 -'exif-lightsource-12' => 'Daylight fluorescent (D 5700 – 7100K)',
2674 -'exif-lightsource-13' => 'Day white fluorescent (N 4600 – 5400K)',
2675 -'exif-lightsource-14' => 'Cool white fluorescent (W 3900 – 4500K)',
2676 -'exif-lightsource-15' => 'White fluorescent (WW 3200 – 3700K)',
2677 -'exif-lightsource-17' => 'Standard light A',
2678 -'exif-lightsource-18' => 'Standard light B',
2679 -'exif-lightsource-19' => 'Standard light C',
2680 -'exif-lightsource-20' => 'D55',
2681 -'exif-lightsource-21' => 'D65',
2682 -'exif-lightsource-22' => 'D75',
2683 -'exif-lightsource-23' => 'D50',
2684 -'exif-lightsource-24' => 'ISO studio tungsten',
 2644+'exif-lightsource-0' => 'Unknown',
 2645+'exif-lightsource-1' => 'Daylight',
 2646+'exif-lightsource-2' => 'Fluorescent',
 2647+'exif-lightsource-3' => 'Tungsten (incandescent light)',
 2648+'exif-lightsource-4' => 'Flash',
 2649+'exif-lightsource-9' => 'Fine weather',
 2650+'exif-lightsource-10' => 'Cloudy weather',
 2651+'exif-lightsource-11' => 'Shade',
 2652+'exif-lightsource-12' => 'Daylight fluorescent (D 5700 – 7100K)',
 2653+'exif-lightsource-13' => 'Day white fluorescent (N 4600 – 5400K)',
 2654+'exif-lightsource-14' => 'Cool white fluorescent (W 3900 – 4500K)',
 2655+'exif-lightsource-15' => 'White fluorescent (WW 3200 – 3700K)',
 2656+'exif-lightsource-17' => 'Standard light A',
 2657+'exif-lightsource-18' => 'Standard light B',
 2658+'exif-lightsource-19' => 'Standard light C',
 2659+'exif-lightsource-20' => 'D55',
 2660+'exif-lightsource-21' => 'D65',
 2661+'exif-lightsource-22' => 'D75',
 2662+'exif-lightsource-23' => 'D50',
 2663+'exif-lightsource-24' => 'ISO studio tungsten',
26852664 'exif-lightsource-255' => 'Other light source',
26862665
26872666 'exif-focalplaneresolutionunit-2' => 'inches',
@@ -2735,11 +2714,11 @@
27362715 'exif-subjectdistancerange-2' => 'Close view',
27372716 'exif-subjectdistancerange-3' => 'Distant view',
27382717
2739 -// Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
 2718+# Pseudotags used for GPSLatitudeRef and GPSDestLatitudeRef
27402719 'exif-gpslatitude-n' => 'North latitude',
27412720 'exif-gpslatitude-s' => 'South latitude',
27422721
2743 -// Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
 2722+# Pseudotags used for GPSLongitudeRef and GPSDestLongitudeRef
27442723 'exif-gpslongitude-e' => 'East longitude',
27452724 'exif-gpslongitude-w' => 'West longitude',
27462725
@@ -2749,152 +2728,149 @@
27502729 'exif-gpsmeasuremode-2' => '2-dimensional measurement',
27512730 'exif-gpsmeasuremode-3' => '3-dimensional measurement',
27522731
2753 -// Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
 2732+# Pseudotags used for GPSSpeedRef and GPSDestDistanceRef
27542733 'exif-gpsspeed-k' => 'Kilometres per hour',
27552734 'exif-gpsspeed-m' => 'Miles per hour',
27562735 'exif-gpsspeed-n' => 'Knots',
27572736
2758 -// Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
 2737+# Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef
27592738 'exif-gpsdirection-t' => 'True direction',
27602739 'exif-gpsdirection-m' => 'Magnetic direction',
27612740
2762 -# external editor support
2763 -'edit-externally' => 'Edit this file using an external application',
 2741+# External editor support
 2742+'edit-externally' => 'Edit this file using an external application',
27642743 'edit-externally-help' => 'See the [http://meta.wikimedia.org/wiki/Help:External_editors setup instructions] for more information.',
27652744
27662745 # 'all' in various places, this might be different for inflected languages
27672746 'recentchangesall' => 'all',
2768 -'imagelistall' => 'all',
2769 -'watchlistall1' => 'all',
2770 -'watchlistall2' => 'all',
2771 -'namespacesall' => 'all',
 2747+'imagelistall' => 'all',
 2748+'watchlistall1' => 'all',
 2749+'watchlistall2' => 'all',
 2750+'namespacesall' => 'all',
27722751
27732752 # E-mail address confirmation
2774 -'confirmemail' => 'Confirm E-mail address',
2775 -'confirmemail_noemail' => 'You do not have a valid email address set in your [[Special:Preferences|user preferences]].',
2776 -'confirmemail_text' => "This wiki requires that you validate your e-mail address
 2753+'confirmemail' => 'Confirm E-mail address',
 2754+'confirmemail_noemail' => 'You do not have a valid email address set in your [[Special:Preferences|user preferences]].',
 2755+'confirmemail_text' => 'This wiki requires that you validate your e-mail address
27772756 before using e-mail features. Activate the button below to send a confirmation
27782757 mail to your address. The mail will include a link containing a code; load the
2779 -link in your browser to confirm that your e-mail address is valid.",
2780 -'confirmemail_pending' => '<div class="error">
 2758+link in your browser to confirm that your e-mail address is valid.',
 2759+'confirmemail_pending' => '<div class="error">
27812760 A confirmation code has already been e-mailed to you; if you recently
27822761 created your account, you may wish to wait a few minutes for it to
27832762 arrive before trying to request a new code.
27842763 </div>',
2785 -'confirmemail_send' => 'Mail a confirmation code',
2786 -'confirmemail_sent' => 'Confirmation e-mail sent.',
2787 -'confirmemail_oncreate' => 'A confirmation code was sent to your e-mail address.
 2764+'confirmemail_send' => 'Mail a confirmation code',
 2765+'confirmemail_sent' => 'Confirmation e-mail sent.',
 2766+'confirmemail_oncreate' => 'A confirmation code was sent to your e-mail address.
27882767 This code is not required to log in, but you will need to provide it before
27892768 enabling any e-mail-based features in the wiki.',
27902769 'confirmemail_sendfailed' => 'Could not send confirmation mail. Check address for invalid characters.
27912770
27922771 Mailer returned: $1',
2793 -'confirmemail_invalid' => 'Invalid confirmation code. The code may have expired.',
2794 -'confirmemail_needlogin' => 'You need to $1 to confirm your email address.',
2795 -'confirmemail_success' => 'Your e-mail address has been confirmed. You may now log in and enjoy the wiki.',
2796 -'confirmemail_loggedin' => 'Your e-mail address has now been confirmed.',
2797 -'confirmemail_error' => 'Something went wrong saving your confirmation.',
 2772+'confirmemail_invalid' => 'Invalid confirmation code. The code may have expired.',
 2773+'confirmemail_needlogin' => 'You need to $1 to confirm your email address.',
 2774+'confirmemail_success' => 'Your e-mail address has been confirmed. You may now log in and enjoy the wiki.',
 2775+'confirmemail_loggedin' => 'Your e-mail address has now been confirmed.',
 2776+'confirmemail_error' => 'Something went wrong saving your confirmation.',
 2777+'confirmemail_subject' => '{{SITENAME}} e-mail address confirmation',
 2778+'confirmemail_body' => 'Someone, probably you from IP address $1, has registered an
 2779+account "$2" with this e-mail address on {{SITENAME}}.
27982780
2799 -'confirmemail_subject' => '{{SITENAME}} e-mail address confirmation',
2800 -'confirmemail_body' => "Someone, probably you from IP address $1, has registered an
2801 -account \"$2\" with this e-mail address on {{SITENAME}}.
2802 -
28032781 To confirm that this account really does belong to you and activate
28042782 e-mail features on {{SITENAME}}, open this link in your browser:
28052783
28062784 $3
28072785
2808 -If this is *not* you, don't follow the link. This confirmation code
2809 -will expire at $4.",
 2786+If this is *not* you, don\'t follow the link. This confirmation code
 2787+will expire at $4.',
28102788
28112789 # Inputbox extension, may be useful in other contexts as well
2812 -'tryexact' => 'Try exact match',
 2790+'tryexact' => 'Try exact match',
28132791 'searchfulltext' => 'Search full text',
2814 -'createarticle' => 'Create article',
 2792+'createarticle' => 'Create article',
28152793
28162794 # Scary transclusion
28172795 'scarytranscludedisabled' => '[Interwiki transcluding is disabled]',
2818 -'scarytranscludefailed' => '[Template fetch failed for $1; sorry]',
2819 -'scarytranscludetoolong' => '[URL is too long; sorry]',
 2796+'scarytranscludefailed' => '[Template fetch failed for $1; sorry]',
 2797+'scarytranscludetoolong' => '[URL is too long; sorry]',
28202798
28212799 # Trackbacks
2822 -'trackbackbox' => '<div id="mw_trackbacks">
 2800+'trackbackbox' => '<div id="mw_trackbacks">
28232801 Trackbacks for this article:<br />
28242802 $1
28252803 </div>',
2826 -'trackback' => '; $4$5 : [$2 $1]',
2827 -'trackbackexcerpt' => '; $4$5 : [$2 $1]: <nowiki>$3</nowiki>',
2828 -'trackbackremove' => ' ([$1 Delete])',
2829 -'trackbacklink' => 'Trackback',
 2804+'trackback' => '; $4$5 : [$2 $1]', # don't translate or duplicate this message to other languages
 2805+'trackbackexcerpt' => '; $4$5 : [$2 $1]: <nowiki>$3</nowiki>', # don't translate or duplicate this message to other languages
 2806+'trackbackremove' => ' ([$1 Delete])',
 2807+'trackbacklink' => 'Trackback',
28302808 'trackbackdeleteok' => 'The trackback was successfully deleted.',
28312809
2832 -
2833 -# delete conflict
2834 -
 2810+# Delete conflict
28352811 'deletedwhileediting' => 'Warning: This page has been deleted after you started editing!',
2836 -'confirmrecreate' => 'User [[User:$1|$1]] ([[User talk:$1|talk]]) deleted this page after you started editing with reason:
2837 -: \'\'$2\'\'
2838 -Please confirm that really want to recreate this page.',
2839 -'recreate' => 'Recreate',
 2812+'confirmrecreate' => "User [[User:$1|$1]] ([[User talk:$1|talk]]) deleted this page after you started editing with reason:
 2813+: ''$2''
 2814+Please confirm that really want to recreate this page.",
 2815+'recreate' => 'Recreate',
28402816
2841 -'unit-pixel' => 'px',
 2817+'unit-pixel' => 'px', # only translate this message to other languages if you have to change it
28422818
28432819 # HTML dump
28442820 'redirectingto' => 'Redirecting to [[$1]]...',
28452821
28462822 # action=purge
2847 -'confirm_purge' => "Clear the cache of this page?\n\n$1",
 2823+'confirm_purge' => 'Clear the cache of this page?
 2824+
 2825+$1',
28482826 'confirm_purge_button' => 'OK',
28492827
2850 -'youhavenewmessagesmulti' => "You have new messages on $1",
2851 -'newtalkseperator' => ',_',
 2828+'youhavenewmessagesmulti' => 'You have new messages on $1',
 2829+'newtalkseperator' => ',_', # don't translate or duplicate this message to other languages
 2830+
28522831 'searchcontaining' => "Search for articles containing ''$1''.",
2853 -'searchnamed' => "Search for articles named ''$1''.",
2854 -'articletitles' => "Articles starting with ''$1''",
2855 -'hideresults' => 'Hide results',
 2832+'searchnamed' => "Search for articles named ''$1''.",
 2833+'articletitles' => "Articles starting with ''$1''",
 2834+'hideresults' => 'Hide results',
28562835
28572836 # DISPLAYTITLE
28582837 'displaytitle' => '(Link to this page as [[$1]])',
28592838
28602839 # Separator for categories in page lists
2861 -# Please don't localise this
2862 -'catseparator' => '|',
 2840+'catseparator' => '|', # don't translate or duplicate this message to other languages
28632841
28642842 'loginlanguagelabel' => 'Language: $1',
2865 -
2866 -# Don't duplicate this in translations; defaults should remain consistent
2867 -'loginlanguagelinks' => "* Deutsch|de
 2843+'loginlanguagelinks' => '* Deutsch|de
28682844 * English|en
28692845 * Esperanto|eo
28702846 * Français|fr
28712847 * Español|es
28722848 * Italiano|it
2873 -* Nederlands|nl",
 2849+* Nederlands|nl', # don't translate or duplicate this message to other languages
28742850
28752851 # Multipage image navigation
2876 -'imgmultipageprev' => '← previous page',
2877 -'imgmultipagenext' => 'next page →',
2878 -'imgmultigo' => 'Go!',
2879 -'imgmultigotopre' => 'Go to page',
2880 -'imgmultigotopost' => '',
 2852+'imgmultipageprev' => '← previous page',
 2853+'imgmultipagenext' => 'next page →',
 2854+'imgmultigo' => 'Go!',
 2855+'imgmultigotopre' => 'Go to page',
 2856+'imgmultigotopost' => '', # only translate this message to other languages if you have to change it
28812857 'imgmultiparseerror' => 'The image file appears to be corrupted or incorrect, so {{SITENAME}} cannot retrieve a list of pages.',
28822858
28832859 # Table pager
2884 -'ascending_abbrev' => 'asc',
2885 -'descending_abbrev' => 'desc',
2886 -'table_pager_next' => 'Next page',
2887 -'table_pager_prev' => 'Previous page',
2888 -'table_pager_first' => 'First page',
2889 -'table_pager_last' => 'Last page',
2890 -'table_pager_limit' => 'Show $1 items per page',
 2860+'ascending_abbrev' => 'asc',
 2861+'descending_abbrev' => 'desc',
 2862+'table_pager_next' => 'Next page',
 2863+'table_pager_prev' => 'Previous page',
 2864+'table_pager_first' => 'First page',
 2865+'table_pager_last' => 'Last page',
 2866+'table_pager_limit' => 'Show $1 items per page',
28912867 'table_pager_limit_submit' => 'Go',
2892 -'table_pager_empty' => 'No results',
 2868+'table_pager_empty' => 'No results',
28932869
28942870 # Auto-summaries
2895 -'autosumm-blank' => 'Removing all content from page',
2896 -'autosumm-replace' => 'Replacing page with \'$1\'',
2897 -'autoredircomment' => 'Redirecting to [[$1]]', # This should be changed to the new naming convention, but existed beforehand.
2898 -'autosumm-new' => 'New page: $1',
 2871+'autosumm-blank' => 'Removing all content from page',
 2872+'autosumm-replace' => "Replacing page with '$1'",
 2873+'autoredircomment' => 'Redirecting to [[$1]]', # This should be changed to the new naming convention, but existed beforehand
 2874+'autosumm-new' => 'New page: $1',
28992875
29002876 # Autoblock whitelist
29012877 'autoblock_whitelist' => 'AOL http://webmaster.info.aol.com/proxyinfo.html
@@ -2918,10 +2894,10 @@
29192895 *205.188.208.0/23
29202896 *205.188.112.0/20
29212897 *205.188.146.144/30
2922 -*207.200.112.0/21',
 2898+*207.200.112.0/21', # don't translate or duplicate this message to other languages
29232899
29242900 # Size units
2925 -'size-bytes' => '$1 B',
 2901+'size-bytes' => '$1 B',
29262902 'size-kilobytes' => '$1 KB',
29272903 'size-megabytes' => '$1 MB',
29282904 'size-gigabytes' => '$1 GB',
@@ -2929,12 +2905,14 @@
29302906 # Live preview
29312907 'livepreview-loading' => 'Loading…',
29322908 'livepreview-ready' => 'Loading… Ready!',
2933 -'livepreview-failed' => "Live preview failed!\nTry normal preview.",
2934 -'livepreview-error' => "Failed to connect: $1 \"$2\"\nTry normal preview.",
 2909+'livepreview-failed' => 'Live preview failed!
 2910+Try normal preview.',
 2911+'livepreview-error' => 'Failed to connect: $1 "$2"
 2912+Try normal preview.',
29352913
29362914 # Friendlier slave lag warnings
29372915 'lag-warn-normal' => 'Changes newer than $1 seconds may not be shown in this list.',
2938 -'lag-warn-high' => 'Due to high database server lag, changes newer than $1 seconds
 2916+'lag-warn-high' => 'Due to high database server lag, changes newer than $1 seconds
29392917 may not be shown in this list.',
29402918
29412919 );
Index: branches/phase3_rev_deleted/includes/Article.php
@@ -609,7 +609,7 @@
610610 function view() {
611611 global $wgUser, $wgOut, $wgRequest, $wgContLang;
612612 global $wgEnableParserCache, $wgStylePath, $wgUseRCPatrol, $wgParser;
613 - global $wgUseTrackbacks, $wgNamespaceRobotPolicies;
 613+ global $wgUseTrackbacks, $wgNamespaceRobotPolicies, $wgArticleRobotPolicies;
614614 $sk = $wgUser->getSkin();
615615
616616 wfProfileIn( __METHOD__ );
@@ -637,6 +637,8 @@
638638 # Discourage indexing of printable versions, but encourage following
639639 if( $wgOut->isPrintable() ) {
640640 $policy = 'noindex,follow';
 641+ } elseif ( isset( $wgArticleRobotPolicies[$this->mTitle->getPrefixedText()] ) ) {
 642+ $policy = $wgArticleRobotPolicies[$this->mTitle->getPrefixedText()];
641643 } elseif( isset( $wgNamespaceRobotPolicies[$ns] ) ) {
642644 # Honour customised robot policies for this namespace
643645 $policy = $wgNamespaceRobotPolicies[$ns];
@@ -780,10 +782,10 @@
781783 # XXX: use $this->mTitle->usCssJsSubpage() when php is fixed/ a workaround is found
782784 if (
783785 $ns == NS_USER &&
784 - preg_match('/\\/[\\w]+\\.(?:css|js)$/', $this->mTitle->getDBkey())
 786+ preg_match('!/[\w]+\.(css|js)$!', $this->mTitle->getDBkey(), $matches)
785787 ) {
786788 $wgOut->addWikiText( wfMsg('clearyourcache'));
787 - $wgOut->addHTML( '<pre>'.htmlspecialchars($this->mContent)."\n</pre>" );
 789+ $wgOut->addHTML( "<pre class=\"mw-user-{$matches[1]}\" dir=\"ltr\">".htmlspecialchars($this->mContent)."\n</pre>" );
788790 } else if ( $rt = Title::newFromRedirect( $text ) ) {
789791 # Display redirect
790792 $imageDir = $wgContLang->isRTL() ? 'rtl' : 'ltr';
@@ -1696,7 +1698,13 @@
16971699 }
16981700
16991701 # Prepare a null revision to be added to the history
1700 - $comment = $wgContLang->ucfirst( wfMsgForContent( $protect ? 'protectedarticle' : 'unprotectedarticle', $this->mTitle->getPrefixedText() ) );
 1702+ $modified = $current != '' && $protect;
 1703+ if ( $protect ) {
 1704+ $comment_type = $modified ? 'modifiedarticleprotection' : 'protectedarticle';
 1705+ } else {
 1706+ $comment_type = 'unprotectedarticle';
 1707+ }
 1708+ $comment = $wgContLang->ucfirst( wfMsgForContent( $comment_type, $this->mTitle->getPrefixedText() ) );
17011709
17021710 foreach( $limit as $action => $restrictions ) {
17031711 # Check if the group level required to edit also can protect pages
@@ -1756,7 +1764,7 @@
17571765 }
17581766
17591767 if( $protect ) {
1760 - $log->addEntry( 'protect', $this->mTitle, trim( $reason . " [$updated]$cascade_description$expiry_description" ) );
 1768+ $log->addEntry( $modified ? 'modify' : 'protect', $this->mTitle, trim( $reason . " [$updated]$cascade_description$expiry_description" ) );
17611769 } else {
17621770 $log->addEntry( 'unprotect', $this->mTitle, $reason );
17631771 }
@@ -2016,11 +2024,10 @@
20172025
20182026
20192027 /**
2020 - * Fetch deletion log
 2028+ * Show relevant lines from the deletion log
20212029 */
2022 - function showLogExtract( &$out ) {
2023 - # Show relevant lines from the deletion log:
2024 - $out->addHTML( "<h2>" . htmlspecialchars( LogPage::logName( 'delete' ) ) . "</h2>\n" );
 2030+ function showLogExtract( $out ) {
 2031+ $out->addHtml( '<h2>' . htmlspecialchars( LogPage::logName( 'delete' ) ) . '</h2>' );
20252032 $logViewer = new LogViewer(
20262033 new LogReader(
20272034 new FauxRequest(
Index: branches/phase3_rev_deleted/includes/SpecialVersion.php
@@ -250,7 +250,10 @@
251251 * @return mixed
252252 */
253253 function arrayToString( $list ) {
254 - if ( ! is_array( $list ) ) {
 254+ if( is_object( $list ) ) {
 255+ $class = get_class( $list );
 256+ return "($class)";
 257+ } elseif ( ! is_array( $list ) ) {
255258 return $list;
256259 } else {
257260 $class = get_class( $list[0] );
Index: branches/phase3_rev_deleted/includes/GlobalFunctions.php
@@ -327,6 +327,20 @@
328328 }
329329
330330 /**
 331+ * Get a message in the user interface language and replace wiki
 332+ * links with clickable ones, escaping other HTML
 333+ *
 334+ * @param string $key Message key
 335+ * @return string
 336+ */
 337+function wfMsgWithLinks( $key ) {
 338+ global $wgUser;
 339+ $args = func_get_args();
 340+ return $wgUser->getSkin()->formatLinksInComment( htmlspecialchars(
 341+ call_user_func_array( 'wfMsg', $args ) ) );
 342+}
 343+
 344+/**
331345 * Same as above except doesn't transform the message
332346 */
333347 function wfMsgNoTrans( $key ) {
@@ -369,6 +383,19 @@
370384 }
371385
372386 /**
 387+ * Get a message in the content language and replace wiki
 388+ * links with clickable ones, escaping other HTML
 389+ *
 390+ * @param string $key Message key
 391+ * @return string
 392+ */
 393+function wfMsgForContentWithLinks( $key ) {
 394+ global $wgUser;
 395+ return $wgUser->getSkin()->formatLinksInComment( htmlspecialchars(
 396+ call_user_func_array( 'wfMsgForContent', func_get_args() ) ) );
 397+}
 398+
 399+/**
373400 * Same as above except doesn't transform the message
374401 */
375402 function wfMsgForContentNoTrans( $key ) {
Index: branches/phase3_rev_deleted/includes/ObjectCache.php
@@ -70,6 +70,8 @@
7171 $wgCaches[CACHE_ACCEL] = new eAccelBagOStuff;
7272 } elseif ( function_exists( 'apc_fetch') ) {
7373 $wgCaches[CACHE_ACCEL] = new APCBagOStuff;
 74+ } elseif( function_exists( 'xcache_get' ) ) {
 75+ $wgCaches[CACHE_ACCEL] = new XCacheBagOStuff();
7476 } elseif ( function_exists( 'mmcache_get' ) ) {
7577 $wgCaches[CACHE_ACCEL] = new TurckBagOStuff;
7678 } else {
Index: branches/phase3_rev_deleted/includes/ExternalStore.php
@@ -41,10 +41,9 @@
4242 return false;
4343
4444 $class='ExternalStore'.ucfirst($proto);
45 - /* Preloaded modules might exist, especially ones serving multiple protocols */
 45+ /* Any custom modules should be added to $wgAutoLoadClasses for on-demand loading */
4646 if (!class_exists($class)) {
47 - if (!include_once($class.'.php'))
48 - return false;
 47+ return false;
4948 }
5049 $store=new $class();
5150 return $store;
Index: branches/phase3_rev_deleted/includes/SpecialBooksources.php
@@ -14,14 +14,14 @@
1515 * ISBN passed to the page, if any
1616 */
1717 private $isbn = '';
18 -
 18+
1919 /**
2020 * Constructor
2121 */
2222 public function __construct() {
2323 parent::__construct( 'Booksources' );
2424 }
25 -
 25+
2626 /**
2727 * Show the special page
2828 *
@@ -36,7 +36,7 @@
3737 if( strlen( $this->isbn ) > 0 )
3838 $this->showList();
3939 }
40 -
 40+
4141 /**
4242 * Trim ISBN and remove characters which aren't required
4343 *
@@ -46,7 +46,7 @@
4747 private function cleanIsbn( $isbn ) {
4848 return trim( preg_replace( '![^0-9X]!', '', $isbn ) );
4949 }
50 -
 50+
5151 /**
5252 * Generate a form to allow users to enter an ISBN
5353 *
@@ -64,7 +64,7 @@
6565 $form .= '</fieldset>';
6666 return $form;
6767 }
68 -
 68+
6969 /**
7070 * Determine where to get the list of book sources from,
7171 * format and output them
@@ -73,19 +73,19 @@
7474 */
7575 private function showList() {
7676 global $wgOut, $wgContLang;
77 -
 77+
7878 # Hook to allow extensions to insert additional HTML,
7979 # e.g. for API-interacting plugins and so on
8080 wfRunHooks( 'BookInformation', array( $this->isbn, &$wgOut ) );
81 -
 81+
8282 # Check for a local page such as Project:Book_sources and use that if available
83 - $title = Title::makeTitleSafe( NS_PROJECT, wfMsg( 'booksources' ) ); # Should this be wfMsgForContent()? -- RC
 83+ $title = Title::makeTitleSafe( NS_PROJECT, wfMsgForContent( 'booksources' ) ); # Show list in content language
8484 if( is_object( $title ) && $title->exists() ) {
8585 $rev = Revision::newFromTitle( $title );
8686 $wgOut->addWikiText( str_replace( 'MAGICNUMBER', $this->isbn, $rev->getText() ) );
8787 return true;
8888 }
89 -
 89+
9090 # Fall back to the defaults given in the language file
9191 $wgOut->addWikiText( wfMsgNoTrans( 'booksources-text' ) );
9292 $wgOut->addHtml( '<ul>' );
Index: branches/phase3_rev_deleted/includes/SpecialWantedpages.php
@@ -63,46 +63,49 @@
6464 $db->dataSeek( $res, 0 );
6565 }
6666
67 -
68 - function formatResult( $skin, $result ) {
 67+ /**
 68+ * Format an individual result
 69+ *
 70+ * @param Skin $skin Skin to use for UI elements
 71+ * @param object $result Result row
 72+ * @return string
 73+ */
 74+ public function formatResult( $skin, $result ) {
6975 global $wgLang;
70 -
7176 $title = Title::makeTitleSafe( $result->namespace, $result->title );
72 -
73 - if( $this->isCached() ) {
74 - # Check existence; which is stored in the link cache
75 - if( !$title->exists() ) {
76 - # Make a redlink
 77+ if( $title instanceof Title ) {
 78+ if( $this->isCached() ) {
 79+ $pageLink = $title->exists()
 80+ ? '<s>' . $skin->makeLinkObj( $title ) . '</s>'
 81+ : $skin->makeBrokenLinkObj( $title );
 82+ } else {
7783 $pageLink = $skin->makeBrokenLinkObj( $title );
78 - } else {
79 - # Make a a struck-out normal link
80 - $pageLink = "<s>" . $skin->makeLinkObj( $title ) . "</s>";
81 - }
 84+ }
 85+ return wfSpecialList( $pageLink, $this->makeWlhLink( $title, $skin, $result ) );
8286 } else {
83 - # Not cached? Don't bother checking existence; it can't
84 - $pageLink = $skin->makeBrokenLinkObj( $title );
 87+ $tsafe = htmlspecialchars( $result->title );
 88+ return "Invalid title in result set; {$tsafe}";
8589 }
86 -
87 - # Make a link to "what links here" if it's required
88 - $wlhLink = $this->nlinks
89 - ? $this->makeWlhLink( $title, $skin,
90 - wfMsgExt( 'nlinks', array( 'parsemag', 'escape'),
91 - $wgLang->formatNum( $result->value ) ) )
92 - : null;
93 -
94 - return wfSpecialList($pageLink, $wlhLink);
9590 }
9691
9792 /**
98 - * Make a "what links here" link for a specified title
99 - * @param $title Title to make the link for
100 - * @param $skin Skin to use
101 - * @param $text Link text
 93+ * Make a "what links here" link for a specified result if required
 94+ *
 95+ * @param Title $title Title to make the link for
 96+ * @param Skin $skin Skin to use
 97+ * @param object $result Result row
10298 * @return string
10399 */
104 - function makeWlhLink( &$title, &$skin, $text ) {
105 - $wlhTitle = SpecialPage::getTitleFor( 'Whatlinkshere' );
106 - return $skin->makeKnownLinkObj( $wlhTitle, $text, 'target=' . $title->getPrefixedUrl() );
 100+ private function makeWlhLink( $title, $skin, $result ) {
 101+ global $wgLang;
 102+ if( $this->nlinks ) {
 103+ $wlh = SpecialPage::getTitleFor( 'Whatlinkshere' );
 104+ $label = wfMsgExt( 'nlinks', array( 'parsemag', 'escape' ),
 105+ $wgLang->formatNum( $result->value ) );
 106+ return $skin->makeKnownLinkObj( $wlh, $label, 'target=' . $title->getPrefixedUrl() );
 107+ } else {
 108+ return null;
 109+ }
107110 }
108111
109112 }
Index: branches/phase3_rev_deleted/includes/IP.php
@@ -22,7 +22,12 @@
2323 define( 'RE_IPV6_ADD', '(:(:' . RE_IPV6_WORD . '){1,7}|' . RE_IPV6_WORD . '(:{1,2}' . RE_IPV6_WORD . '|::$){1,7})' );
2424 define( 'RE_IPV6_BLOCK', RE_IPV6_ADD . '\/' . RE_IPV6_PREFIX );
2525 // This might be useful for regexps used elsewhere, matches any IPv6 or IPv6 address or network
26 -define( 'IP_ADDRESS_STRING', RE_IP_ADD . '(\/' . RE_IP_PREFIX . '|)|' . RE_IPV6_ADD . '(\/' . RE_IPV6_PREFIX . '|)');
 26+define( 'IP_ADDRESS_STRING',
 27+ '(?:' .
 28+ RE_IP_ADD . '(\/' . RE_IP_PREFIX . '|)' .
 29+ '|' .
 30+ RE_IPV6_ADD . '(\/' . RE_IPV6_PREFIX . '|)' .
 31+ ')' );
2732
2833 /**
2934 * A collection of public static functions to play with IP address
Index: branches/phase3_rev_deleted/includes/SpecialEmailuser.php
@@ -45,6 +45,13 @@
4646 return;
4747 }
4848
 49+ if ( $wgUser->isBlockedFromEmailUser() ) {
 50+ // User has been blocked from sending e-mail. Show the std blocked form.
 51+ wfDebug( "User is blocked from sending e-mail.\n" );
 52+ $wgOut->blockedPage();
 53+ return;
 54+ }
 55+
4956 $f = new EmailUserForm( $nu );
5057
5158 if ( "success" == $action ) {
Index: branches/phase3_rev_deleted/includes/Block.php
@@ -15,7 +15,8 @@
1616 class Block
1717 {
1818 /* public*/ var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId, $mExpiry,
19 - $mRangeStart, $mRangeEnd, $mAnonOnly, $mEnableAutoblock, $mHideName;
 19+ $mRangeStart, $mRangeEnd, $mAnonOnly, $mEnableAutoblock, $mHideName,
 20+ $mBlockEmail;
2021 /* private */ var $mNetworkBits, $mIntegerAddr, $mForUpdate, $mFromMaster, $mByName;
2122
2223 const EB_KEEP_EXPIRED = 1;
@@ -24,7 +25,7 @@
2526
2627 function __construct( $address = '', $user = 0, $by = 0, $reason = '',
2728 $timestamp = '' , $auto = 0, $expiry = '', $anonOnly = 0, $createAccount = 0, $enableAutoblock = 0,
28 - $hideName = 0 )
 29+ $hideName = 0, $blockEmail = 0 )
2930 {
3031 $this->mId = 0;
3132 # Expand valid IPv6 addresses
@@ -40,7 +41,7 @@
4142 $this->mExpiry = self::decodeExpiry( $expiry );
4243 $this->mEnableAutoblock = $enableAutoblock;
4344 $this->mHideName = $hideName;
44 -
 45+ $this->mBlockEmail = $blockEmail;
4546 $this->mForUpdate = false;
4647 $this->mFromMaster = false;
4748 $this->mByName = false;
@@ -76,7 +77,7 @@
7778 $this->mAddress = $this->mReason = $this->mTimestamp = '';
7879 $this->mId = $this->mAnonOnly = $this->mCreateAccount =
7980 $this->mEnableAutoblock = $this->mAuto = $this->mUser =
80 - $this->mBy = $this->mHideName = 0;
 81+ $this->mBy = $this->mHideName = $this->mBlockEmail = 0;
8182 $this->mByName = false;
8283 }
8384
@@ -262,6 +263,7 @@
263264 $this->mAnonOnly = $row->ipb_anon_only;
264265 $this->mCreateAccount = $row->ipb_create_account;
265266 $this->mEnableAutoblock = $row->ipb_enable_autoblock;
 267+ $this->mBlockEmail = $row->ipb_block_email;
266268 $this->mHideName = $row->ipb_deleted;
267269 $this->mId = $row->ipb_id;
268270 $this->mExpiry = self::decodeExpiry( $row->ipb_expiry );
@@ -371,6 +373,7 @@
372374 # Unset ipb_enable_autoblock for IP blocks, makes no sense
373375 if ( !$this->mUser ) {
374376 $this->mEnableAutoblock = 0;
 377+ $this->mBlockEmail = 0; //Same goes for email...
375378 }
376379
377380 # Don't collide with expired blocks
@@ -392,7 +395,8 @@
393396 'ipb_expiry' => self::encodeExpiry( $this->mExpiry, $dbw ),
394397 'ipb_range_start' => $this->mRangeStart,
395398 'ipb_range_end' => $this->mRangeEnd,
396 - 'ipb_deleted' => $this->mHideName
 399+ 'ipb_deleted' => $this->mHideName,
 400+ 'ipb_block_email' => $this->mBlockEmail
397401 ), 'Block::insert', array( 'IGNORE' )
398402 );
399403 $affected = $dbw->affectedRows();
Index: branches/phase3_rev_deleted/includes/DatabaseOracle.php
@@ -675,10 +675,19 @@
676676 }
677677
678678 function ping() {
679 - wfDebug( "Function ping() not written for DatabasePostgres.php yet");
 679+ wfDebug( "Function ping() not written for DatabaseOracle.php yet");
680680 return true;
681681 }
682682
 683+ /**
 684+ * How lagged is this slave?
 685+ *
 686+ * @return int
 687+ */
 688+ public function getLag() {
 689+ # Not implemented for Oracle
 690+ return 0;
 691+ }
683692
684693 } // end DatabaseOracle class
685694
Index: branches/phase3_rev_deleted/includes/QueryPage.php
@@ -25,6 +25,7 @@
2626 array( 'MostcategoriesPage', 'Mostcategories' ),
2727 array( 'MostimagesPage', 'Mostimages' ),
2828 array( 'MostlinkedCategoriesPage', 'Mostlinkedcategories' ),
 29+ array( 'SpecialMostlinkedtemplates', 'Mostlinkedtemplates' ),
2930 array( 'MostlinkedPage', 'Mostlinked' ),
3031 array( 'MostrevisionsPage', 'Mostrevisions' ),
3132 array( 'FewestrevisionsPage', 'Fewestrevisions' ),
@@ -33,6 +34,7 @@
3435 array( 'UncategorizedCategoriesPage', 'Uncategorizedcategories' ),
3536 array( 'UncategorizedPagesPage', 'Uncategorizedpages' ),
3637 array( 'UncategorizedImagesPage', 'Uncategorizedimages' ),
 38+ array( 'UncategorizedTemplatesPage', 'Uncategorizedtemplates' ),
3739 array( 'UnusedCategoriesPage', 'Unusedcategories' ),
3840 array( 'UnusedimagesPage', 'Unusedimages' ),
3941 array( 'WantedCategoriesPage', 'Wantedcategories' ),
Index: branches/phase3_rev_deleted/includes/MacBinary.php
@@ -100,7 +100,7 @@
101101
102102 fseek( $this->handle, 0 );
103103 $head = fread( $this->handle, 128 );
104 - $this->hexdump( $head );
 104+ #$this->hexdump( $head );
105105
106106 if( strlen( $head ) < 128 ) {
107107 wfDebug( "$fname: couldn't read full MacBinary header\n" );
Index: branches/phase3_rev_deleted/includes/ProtectionForm.php
@@ -27,6 +27,7 @@
2828 var $mRestrictions = array();
2929 var $mReason = '';
3030 var $mCascade = false;
 31+ var $mFileOnly = false;
3132 var $mExpiry = null;
3233
3334 function __construct( &$article ) {
@@ -42,6 +43,14 @@
4344 // Fixme: this form currently requires individual selections,
4445 // but the db allows multiples separated by commas.
4546 $this->mRestrictions[$action] = implode( '', $this->mTitle->getRestrictions( $action ) );
 47+ // For Images only, see if only the file is protected...
 48+ // We want to list EITHER the edit OR upload rights in the db,
 49+ // otherwise ProtectedPages may show dups when 'Upload' is selected
 50+ if( $action=='edit' && !$this->mRestrictions['edit'] && $this->mTitle->getRestrictions('upload') ) {
 51+ $this->mFileOnly = true;
 52+ // Show these under the edit box, for viewing purposes only
 53+ $this->mRestrictions['edit'] = implode( '', $this->mTitle->getRestrictions( 'upload' ) );
 54+ }
4655 }
4756
4857 $this->mCascade = $this->mTitle->areRestrictionsCascading();
@@ -65,6 +74,7 @@
6675 $this->mReason = $wgRequest->getText( 'mwProtect-reason' );
6776 $this->mCascade = $wgRequest->getBool( 'mwProtect-cascade' );
6877 $this->mExpiry = $wgRequest->getText( 'mwProtect-expiry' );
 78+ $this->mFileOnly = $wgRequest->getText( 'mwProtect-fileonly' );
6979
7080 foreach( $wgRestrictionTypes as $action ) {
7181 $val = $wgRequest->getVal( "mwProtect-level-$action" );
@@ -184,10 +194,25 @@
185195
186196 }
187197
 198+ // For images, the edit right is more general than the upload right
 199+ if( $this->mTitle->getNamespace()==NS_IMAGE ) {
 200+ if( $this->mFileOnly ) {
 201+ $this->mRestrictions['upload'] = $this->mRestrictions['edit'];
 202+ $this->mRestrictions['edit'] = '';
 203+ }
 204+ }
 205+
188206 $ok = $this->mArticle->updateRestrictions( $this->mRestrictions, $this->mReason, $this->mCascade, $expiry );
189207 if( !$ok ) {
190208 throw new FatalError( "Unknown error at restriction save time." );
191209 }
 210+
 211+ if( $wgRequest->getCheck( 'mwProtectWatch' ) ) {
 212+ $this->mArticle->doWatch();
 213+ } elseif( $this->mTitle->userIsWatching() ) {
 214+ $this->mArticle->doUnwatch();
 215+ }
 216+
192217 return $ok;
193218 }
194219
@@ -232,13 +257,19 @@
233258 $out .= "</tbody>\n";
234259 $out .= "</table>\n";
235260
 261+ $out .= "<table>\n";
 262+ $out .= "<tbody>\n";
 263+
236264 global $wgEnableCascadingProtection;
 265+
 266+ if( $this->mTitle->getNamespace() == NS_IMAGE )
 267+ $out .= '<p>' . $this->buildUploadInput() . '</p>';
237268
238269 if ($wgEnableCascadingProtection)
239 - $out .= $this->buildCascadeInput();
 270+ $out .= '<tr><td></td><td>' . $this->buildCascadeInput() . "</td></tr>\n";
240271
241 - $out .= "<table>\n";
242 - $out .= "<tbody>\n";
 272+ if( !$this->disabled )
 273+ $out .= '<tr><td></td><td>' . $this->buildWatchInput() . "</td></tr>\n";
243274
244275 $out .= $this->buildExpiryInput();
245276
@@ -302,6 +333,12 @@
303334 'value' => $this->mReason ) );
304335 }
305336
 337+ function buildUploadInput() {
 338+ $id = 'mwProtect-fileonly';
 339+ $ci = wfCheckLabel( wfMsg( 'protect-fileonly' ), $id, $id, $this->mFileOnly, $this->disabledAttrib);
 340+ return $ci;
 341+ }
 342+
306343 function buildCascadeInput() {
307344 $id = 'mwProtect-cascade';
308345 $ci = wfCheckLabel( wfMsg( 'protect-cascade' ), $id, $id, $this->mCascade, $this->disabledAttrib);
@@ -309,23 +346,22 @@
310347 }
311348
312349 function buildExpiryInput() {
313 - $id = 'mwProtect-expiry';
314 -
315 - $ci = "<tr> <td align=\"right\">";
316 - $ci .= wfElement( 'label', array (
317 - 'id' => "$id-label",
318 - 'for' => $id ),
319 - wfMsg( 'protectexpiry' ) );
320 - $ci .= "</td> <td align=\"left\">";
321 - $ci .= wfElement( 'input', array(
322 - 'size' => 60,
323 - 'name' => $id,
324 - 'id' => $id,
325 - 'value' => $this->mExpiry ) + $this->disabledAttrib );
326 - $ci .= "</td></tr>";
327 -
328 - return $ci;
 350+ $attribs = array( 'id' => 'expires' ) + $this->disabledAttrib;
 351+ return '<tr>'
 352+ . '<td><label for="expires">' . wfMsgWithLinks( 'protectexpiry' ) . '</label></td>'
 353+ . '<td>' . Xml::input( 'mwProtect-expiry', 60, $this->mExpiry, $attribs ) . '</td>'
 354+ . '</tr>';
329355 }
 356+
 357+ function buildWatchInput() {
 358+ global $wgUser;
 359+ return Xml::checkLabel(
 360+ wfMsg( 'watchthis' ),
 361+ 'mwProtectWatch',
 362+ 'mwProtectWatch',
 363+ $this->mTitle->userIsWatching() || $wgUser->getOption( 'watchdefault' )
 364+ );
 365+ }
330366
331367 function buildSubmit() {
332368 return wfElement( 'input', array(
@@ -360,7 +396,7 @@
361397 * @access private
362398 */
363399 function showLogExtract( &$out ) {
364 - # Show relevant lines from the deletion log:
 400+ # Show relevant lines from the protection log:
365401 $out->addHTML( "<h2>" . htmlspecialchars( LogPage::logName( 'protect' ) ) . "</h2>\n" );
366402 $logViewer = new LogViewer(
367403 new LogReader(
Index: branches/phase3_rev_deleted/includes/DifferenceEngine.php
@@ -47,7 +47,7 @@
4848 # Show diff between revision $old and the previous one.
4949 # Get previous one from DB.
5050 #
51 - $this->mNewid = intval($old);
 51+ $this->mNewid = intval($old);
5252
5353 $this->mOldid = $this->mTitle->getPreviousRevisionID( $this->mNewid );
5454
@@ -63,6 +63,13 @@
6464 $this->mNewid = 0;
6565 }
6666
 67+ } else if( 'cur' === $new ) {
 68+ # Show diff between revision $old and the current one.
 69+ # Get previous one from DB.
 70+ #
 71+ $this->mNewid = $this->mTitle->getLatestRevID();
 72+
 73+ $this->mOldid = intval($old);
6774 } else {
6875 $this->mOldid = intval($old);
6976 $this->mNewid = intval($new);
@@ -333,11 +340,22 @@
334341 $wgOut->addWikitext( wfMsg( 'missingarticle', "<nowiki>(fixme, bug)</nowiki>" ) );
335342 return false;
336343 } else {
337 - $wgOut->addStyle( 'common/diff.css' );
 344+ $this->showDiffStyle();
338345 $wgOut->addHTML( $diff );
339346 return true;
340347 }
341348 }
 349+
 350+ /**
 351+ * Add style sheets and supporting JS for diff display.
 352+ */
 353+ function showDiffStyle() {
 354+ global $wgStylePath, $wgStyleVersion, $wgOut;
 355+ $wgOut->addStyle( 'common/diff.css' );
 356+
 357+ // JS is needed to detect old versions of Mozilla to work around an annoyance bug.
 358+ $wgOut->addScript( "<script type=\"text/javascript\" src=\"$wgStylePath/common/diff.js?$wgStyleVersion\"></script>" );
 359+ }
342360
343361 /**
344362 * Get diff table, including header
@@ -588,6 +606,8 @@
589607 if( is_null( $this->mNewRev ) ) {
590608 return false;
591609 }
 610+
 611+ $this->mNewid = $this->mNewRev->getId(); // Make this explicit, for undo links
592612
593613 // Set assorted variables
594614 $timestamp = $wgLang->timeanddate( $this->mNewRev->getTimestamp(), true );
Index: branches/phase3_rev_deleted/includes/DatabasePostgres.php
@@ -601,13 +601,9 @@
602602 if ( !$res ) {
603603 return NULL;
604604 }
605 -
606605 while ( $row = $this->fetchObject( $res ) ) {
607606 if ( $row->indexname == $index ) {
608607 return $row;
609 -
610 - // BUG: !!!! This code needs to be synced up with database.php
611 -
612608 }
613609 }
614610 return false;
@@ -923,7 +919,7 @@
924920 $count = $res ? pg_num_rows($res) : 0;
925921 if ($res)
926922 $this->freeResult( $res );
927 - return $count;
 923+ return $count ? true : false;
928924 }
929925
930926 /*
@@ -1102,10 +1098,10 @@
11031099 $this->doQuery("COMMIT");
11041100 }
11051101
1106 - function encodeBlob($b) {
 1102+ function encodeBlob( $b ) {
11071103 return array('bytea',pg_escape_bytea($b));
11081104 }
1109 - function decodeBlob($b) {
 1105+ function decodeBlob( $b ) {
11101106 return pg_unescape_bytea( $b );
11111107 }
11121108
@@ -1177,8 +1173,17 @@
11781174 wfDebug( "Function ping() not written for DatabasePostgres.php yet");
11791175 return true;
11801176 }
 1177+
 1178+ /**
 1179+ * How lagged is this slave?
 1180+ *
 1181+ * @return int
 1182+ */
 1183+ public function getLag() {
 1184+ # Not implemented for PostgreSQL
 1185+ return 0;
 1186+ }
11811187
1182 -
11831188 } // end DatabasePostgres class
11841189
11851190 ?>
Index: branches/phase3_rev_deleted/includes/SkinTemplate.php
@@ -440,7 +440,8 @@
441441 // XXX: attach this from javascript, same with section editing
442442 if($this->iseditable && $wgUser->getOption("editondblclick") )
443443 {
444 - $tpl->set('body_ondblclick', 'document.location = "' .$content_actions['edit']['href'] .'";');
 444+ $encEditUrl = wfEscapeJsString( $this->mTitle->getLocalUrl( $this->editUrlOptions() ) );
 445+ $tpl->set('body_ondblclick', 'document.location = "' . $encEditUrl . '";');
445446 } else {
446447 $tpl->set('body_ondblclick', false);
447448 }
Index: branches/phase3_rev_deleted/includes/SpecialConfirmemail.php
@@ -1,31 +1,30 @@
22 <?php
33
44 /**
5 - * Main execution point
6 - *
7 - * @param $par Parameters passed to the page
8 - */
9 -function wfSpecialConfirmemail( $par ) {
10 - $form = new EmailConfirmation();
11 - $form->execute( $par );
12 -}
13 -
14 -/**
155 * Special page allows users to request email confirmation message, and handles
166 * processing of the confirmation code when the link in the email is followed
177 *
188 * @addtogroup SpecialPage
 9+ * @author Brion Vibber
1910 * @author Rob Church <robchur@gmail.com>
2011 */
21 -class EmailConfirmation extends SpecialPage {
 12+class EmailConfirmation extends UnlistedSpecialPage {
2213
2314 /**
 15+ * Constructor
 16+ */
 17+ public function __construct() {
 18+ parent::__construct( 'Confirmemail' );
 19+ }
 20+
 21+ /**
2422 * Main execution point
2523 *
2624 * @param $code Confirmation code passed to the page
2725 */
2826 function execute( $code ) {
2927 global $wgUser, $wgOut;
 28+ $this->setHeaders();
3029 if( empty( $code ) ) {
3130 if( $wgUser->isLoggedIn() ) {
3231 if( User::isValidEmailAddr( $wgUser->getEmail() ) ) {
Index: branches/phase3_rev_deleted/includes/SpecialSearch.php
@@ -185,6 +185,7 @@
186186 } else {
187187 $wgOut->addWikiText( '==' . wfMsg( 'notitlematches' ) . "==\n" );
188188 }
 189+ $titleMatches->free();
189190 }
190191
191192 if( $textMatches ) {
@@ -195,6 +196,7 @@
196197 # Don't show the 'no text matches' if we received title matches
197198 $wgOut->addWikiText( '==' . wfMsg( 'notextmatches' ) . "==\n" );
198199 }
 200+ $textMatches->free();
199201 }
200202
201203 if ( $num == 0 ) {
Index: branches/phase3_rev_deleted/includes/Linker.php
@@ -437,6 +437,7 @@
438438 * @param boolean $thumb shows image as thumbnail in a frame
439439 * @param string $manual_thumb image name for the manual thumbnail
440440 * @param string $valign vertical alignment: baseline, sub, super, top, text-top, middle, bottom, text-bottom
 441+ * @param string $timestamp: revision time
441442 * @return string
442443 */
443444 function makeImageLinkObj( $nt, $label, $alt, $align = '', $params = array(), $framed = false,
@@ -627,34 +628,38 @@
628629 }
629630
630631 /**
631 - * Pass a title object, not a title string
 632+ * Make a "broken" link to an image
 633+ *
 634+ * @param Title $title Image title
 635+ * @param string $text Link label
 636+ * @param string $query Query string
 637+ * @param string $trail Link trail
 638+ * @param string $prefix Link prefix
 639+ * @return string
632640 */
633 - function makeBrokenImageLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
634 - # Fail gracefully
635 - if ( ! isset($nt) ) {
636 - # throw new MWException();
 641+ public function makeBrokenImageLinkObj( $title, $text = '', $query = '', $trail = '', $prefix = '' ) {
 642+ global $wgEnableUploads;
 643+ if( $title instanceof Title ) {
 644+ wfProfileIn( __METHOD__ );
 645+ if( $wgEnableUploads ) {
 646+ $upload = SpecialPage::getTitleFor( 'Upload' );
 647+ if( $text == '' )
 648+ $text = htmlspecialchars( $title->getPrefixedText() );
 649+ $q = 'wpDestFile=' . $title->getPartialUrl();
 650+ if( $query != '' )
 651+ $q .= '&' . $query;
 652+ list( $inside, $trail ) = self::splitTrail( $trail );
 653+ $style = $this->getInternalLinkAttributesObj( $title, $text, 'yes' );
 654+ wfProfileOut( __METHOD__ );
 655+ return '<a href="' . $upload->escapeLocalUrl( $q ) . '"'
 656+ . $style . '>' . $prefix . $text . $inside . '</a>' . $trail;
 657+ } else {
 658+ wfProfileOut( __METHOD__ );
 659+ return $this->makeKnownLinkObj( $title, $text, $query, $trail, $prefix );
 660+ }
 661+ } else {
637662 return "<!-- ERROR -->{$prefix}{$text}{$trail}";
638663 }
639 -
640 - $fname = 'Linker::makeBrokenImageLinkObj';
641 - wfProfileIn( $fname );
642 -
643 - $q = 'wpDestFile=' . urlencode( $nt->getDBkey() );
644 - if ( '' != $query ) {
645 - $q .= "&$query";
646 - }
647 - $uploadTitle = SpecialPage::getTitleFor( 'Upload' );
648 - $url = $uploadTitle->escapeLocalURL( $q );
649 -
650 - if ( '' == $text ) {
651 - $text = htmlspecialchars( $nt->getPrefixedText() );
652 - }
653 - $style = $this->getInternalLinkAttributesObj( $nt, $text, "yes" );
654 - list( $inside, $trail ) = Linker::splitTrail( $trail );
655 - $s = "<a href=\"{$url}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
656 -
657 - wfProfileOut( $fname );
658 - return $s;
659664 }
660665
661666 /** @deprecated use Linker::makeMediaLinkObj() */
@@ -684,7 +689,7 @@
685690 $class = 'internal';
686691 } else {
687692 $upload = SpecialPage::getTitleFor( 'Upload' );
688 - $url = $upload->getLocalUrl( 'wpDestFile=' . urlencode( $title->getText() ) );
 693+ $url = $upload->getLocalUrl( 'wpDestFile=' . urlencode( $title->getDbKey() ) );
689694 $class = 'new';
690695 }
691696 $alt = htmlspecialchars( $title->getText() );
@@ -855,26 +860,6 @@
856861 }
857862
858863 /**
859 - * Generate a user link if the current user is allowed to view it
860 - * @param File $file
861 - * @param $isPublic, bool, show only if all users can see it
862 - * @return string HTML
863 - */
864 - function fileUserLink( $file, $isPublic = false ) {
865 - if( $file->isDeleted( File::DELETED_USER ) && $isPublic ) {
866 - $link = wfMsgHtml( 'rev-deleted-user' );
867 - } else if( $file->userCan( File::DELETED_USER ) ) {
868 - $link = $this->userLink( $file->user, $file->userText );
869 - } else {
870 - $link = wfMsgHtml( 'rev-deleted-user' );
871 - }
872 - if( $file->isDeleted( File::DELETED_USER ) ) {
873 - return '<span class="history-deleted">' . $link . '</span>';
874 - }
875 - return $link;
876 - }
877 -
878 - /**
879864 * Generate a user tool link cluster if the current user is allowed to view it
880865 * @param $rev Revision object.
881866 * @param $isPublic, bool, show only if all users can see it
@@ -921,27 +906,6 @@
922907 }
923908 return $link;
924909 }
925 -
926 - /**
927 - * Generate a user tool link cluster if the current user is allowed to view it
928 - * @param File $file
929 - * @param $isPublic, bool, show only if all users can see it
930 - * @return string HTML
931 - */
932 - function fileUserTools( $file, $isPublic = false ) {
933 - if( $file->isDeleted( Revision::DELETED_USER ) && $isPublic ) {
934 - $link = wfMsgHtml( 'rev-deleted-user' );
935 - } else if( $file->userCan( Revision::DELETED_USER ) ) {
936 - $link = $this->userLink( $file->user, $file->userText ) .
937 - $this->userToolLinks( $file->user, $file->userText );
938 - } else {
939 - $link = wfMsgHtml( 'rev-deleted-user' );
940 - }
941 - if( $file->isDeleted( Revision::DELETED_USER ) ) {
942 - return '<span class="history-deleted">' . $link . '</span>';
943 - }
944 - return $link;
945 - }
946910
947911 /**
948912 * This function is called by all recent changes variants, by the page history,
@@ -1024,12 +988,13 @@
1025989 }
1026990
1027991 /**
1028 - * Format regular and media links - all other wiki formatting is ignored
1029 - * Called by Linker::formatComment.
1030 - * @param $comment The comment text.
1031 - * @return Comment text with links using HTML.
 992+ * Formats wiki links and media links in text; all other wiki formatting
 993+ * is ignored
 994+ *
 995+ * @param string $comment Text to format links in
 996+ * @return string
1032997 */
1033 - private function formatLinksInComment( $comment ) {
 998+ public function formatLinksInComment( $comment ) {
1034999 global $wgContLang;
10351000
10361001 $medians = '(?:' . preg_quote( Namespace::getCanonicalName( NS_MEDIA ), '/' ) . '|';
@@ -1131,27 +1096,6 @@
11321097 return $block;
11331098 }
11341099
1135 - /**
1136 - * Wrap and format the given file's comment block, if the current
1137 - * user is allowed to view it.
1138 - *
1139 - * @param File $file
1140 - * @return string HTML
1141 - */
1142 - function fileComment( $file, $isPublic = false ) {
1143 - if( $file->isDeleted( File::DELETED_COMMENT ) && $isPublic ) {
1144 - $block = ' ' . wfMsgHtml( 'rev-deleted-comment' );
1145 - } else if( $file->userCan( File::DELETED_COMMENT ) ) {
1146 - $block = $this->commentBlock( $file->description );
1147 - } else {
1148 - $block = ' ' . wfMsgHtml( 'rev-deleted-comment' );
1149 - }
1150 - if( $file->isDeleted( File::DELETED_COMMENT ) ) {
1151 - return "<span class=\"history-deleted\">$block</span>";
1152 - }
1153 - return $block;
1154 - }
1155 -
11561100 /** @todo document */
11571101 function tocIndent() {
11581102 return "\n<ul>";
@@ -1200,13 +1144,14 @@
12011145 /** @todo document */
12021146 public function editSectionLinkForOther( $title, $section ) {
12031147 global $wgContLang;
1204 -
12051148 $title = Title::newFromText( $title );
12061149 $editurl = '&section='.$section;
12071150 $url = $this->makeKnownLinkObj( $title, wfMsg('editsection'), 'action=edit'.$editurl );
1208 -
1209 - return "<span class=\"editsection\">[".$url."]</span>";
1210 -
 1151+ $result = null;
 1152+ wfRunHooks( 'EditSectionLinkForOther', array( &$this, $title, $section, $url, &$result ) );
 1153+ return is_null( $result )
 1154+ ? "<span class=\"editsection\">[{$url}]</span>"
 1155+ : "<span class=\"editsection\">[{$result}]</span>";
12111156 }
12121157
12131158 /**
@@ -1216,12 +1161,14 @@
12171162 */
12181163 public function editSectionLink( $nt, $section, $hint='' ) {
12191164 global $wgContLang;
1220 -
12211165 $editurl = '&section='.$section;
12221166 $hint = ( $hint=='' ) ? '' : ' title="' . wfMsgHtml( 'editsectionhint', htmlspecialchars( $hint ) ) . '"';
12231167 $url = $this->makeKnownLinkObj( $nt, wfMsg('editsection'), 'action=edit'.$editurl, '', '', '', $hint );
1224 -
1225 - return "<span class=\"editsection\">[".$url."]</span>";
 1168+ $result = null;
 1169+ wfRunHooks( 'EditSectionLink', array( &$this, $nt, $section, $hint, $url, &$result ) );
 1170+ return is_null( $result )
 1171+ ? "<span class=\"editsection\">[{$url}]</span>"
 1172+ : "<span class=\"editsection\">[{$result}]</span>";
12261173 }
12271174
12281175 /**
Index: branches/phase3_rev_deleted/includes/Parser.php
@@ -2431,17 +2431,17 @@
24322432
24332433 switch ( $index ) {
24342434 case 'currentmonth':
2435 - return $varCache[$index] = $wgContLang->formatNum( date( 'm', $ts ) );
 2435+ return $varCache[$index] = $wgContLang->formatNum( gmdate( 'm', $ts ) );
24362436 case 'currentmonthname':
2437 - return $varCache[$index] = $wgContLang->getMonthName( date( 'n', $ts ) );
 2437+ return $varCache[$index] = $wgContLang->getMonthName( gmdate( 'n', $ts ) );
24382438 case 'currentmonthnamegen':
2439 - return $varCache[$index] = $wgContLang->getMonthNameGen( date( 'n', $ts ) );
 2439+ return $varCache[$index] = $wgContLang->getMonthNameGen( gmdate( 'n', $ts ) );
24402440 case 'currentmonthabbrev':
2441 - return $varCache[$index] = $wgContLang->getMonthAbbreviation( date( 'n', $ts ) );
 2441+ return $varCache[$index] = $wgContLang->getMonthAbbreviation( gmdate( 'n', $ts ) );
24422442 case 'currentday':
2443 - return $varCache[$index] = $wgContLang->formatNum( date( 'j', $ts ) );
 2443+ return $varCache[$index] = $wgContLang->formatNum( gmdate( 'j', $ts ) );
24442444 case 'currentday2':
2445 - return $varCache[$index] = $wgContLang->formatNum( date( 'd', $ts ) );
 2445+ return $varCache[$index] = $wgContLang->formatNum( gmdate( 'd', $ts ) );
24462446 case 'localmonth':
24472447 return $varCache[$index] = $wgContLang->formatNum( $localMonth );
24482448 case 'localmonthname':
@@ -2515,19 +2515,19 @@
25162516 case 'subjectspacee':
25172517 return( wfUrlencode( $this->mTitle->getSubjectNsText() ) );
25182518 case 'currentdayname':
2519 - return $varCache[$index] = $wgContLang->getWeekdayName( date( 'w', $ts ) + 1 );
 2519+ return $varCache[$index] = $wgContLang->getWeekdayName( gmdate( 'w', $ts ) + 1 );
25202520 case 'currentyear':
2521 - return $varCache[$index] = $wgContLang->formatNum( date( 'Y', $ts ), true );
 2521+ return $varCache[$index] = $wgContLang->formatNum( gmdate( 'Y', $ts ), true );
25222522 case 'currenttime':
25232523 return $varCache[$index] = $wgContLang->time( wfTimestamp( TS_MW, $ts ), false, false );
25242524 case 'currenthour':
2525 - return $varCache[$index] = $wgContLang->formatNum( date( 'H', $ts ), true );
 2525+ return $varCache[$index] = $wgContLang->formatNum( gmdate( 'H', $ts ), true );
25262526 case 'currentweek':
25272527 // @bug 4594 PHP5 has it zero padded, PHP4 does not, cast to
25282528 // int to remove the padding
2529 - return $varCache[$index] = $wgContLang->formatNum( (int)date( 'W', $ts ) );
 2529+ return $varCache[$index] = $wgContLang->formatNum( (int)gmdate( 'W', $ts ) );
25302530 case 'currentdow':
2531 - return $varCache[$index] = $wgContLang->formatNum( date( 'w', $ts ) );
 2531+ return $varCache[$index] = $wgContLang->formatNum( gmdate( 'w', $ts ) );
25322532 case 'localdayname':
25332533 return $varCache[$index] = $wgContLang->getWeekdayName( $localDayOfWeek + 1 );
25342534 case 'localyear':
@@ -3277,7 +3277,7 @@
32783278
32793279 if( $skip ) {
32803280 $text = false;
3281 - $this->mOutput->addTemplate( $title, $title->getArticleID(), 0 );
 3281+ $this->mOutput->addTemplate( $title, $title->getArticleID(), null );
32823282 break;
32833283 }
32843284 $rev = $id ? Revision::newFromId( $id ) : Revision::newFromTitle( $title );
@@ -3405,7 +3405,13 @@
34063406 }
34073407
34083408 /**
3409 - * Detect __TOC__ magic word and set a placeholder
 3409+ * Find the first __TOC__ magic word and set a <!--MWTOC-->
 3410+ * placeholder that will then be replaced by the real TOC in
 3411+ * ->formatHeadings, this works because at this points real
 3412+ * comments will have already been discarded by the sanitizer.
 3413+ *
 3414+ * Any additional __TOC__ magic words left over will be discarded
 3415+ * as there can only be one TOC on the page.
34103416 */
34113417 function stripToc( $text ) {
34123418 # if the string __NOTOC__ (not case-sensitive) occurs in the HTML,
@@ -3797,11 +3803,16 @@
37983804 * @private
37993805 */
38003806 function getUserSig( &$user ) {
 3807+ global $wgMaxSigChars;
 3808+
38013809 $username = $user->getName();
38023810 $nickname = $user->getOption( 'nickname' );
38033811 $nickname = $nickname === '' ? $username : $nickname;
3804 -
3805 - if( $user->getBoolOption( 'fancysig' ) !== false ) {
 3812+
 3813+ if( strlen( $nickname ) > $wgMaxSigChars ) {
 3814+ $nickname = $username;
 3815+ wfDebug( __METHOD__ . ": $username has overlong signature.\n" );
 3816+ } elseif( $user->getBoolOption( 'fancysig' ) !== false ) {
38063817 # Sig. might contain markup; validate this
38073818 if( $this->validateSig( $nickname ) !== false ) {
38083819 # Validated; clean up (if needed) and return it
@@ -4379,7 +4390,7 @@
43804391 $ig->setHeights( $params['heights'] );
43814392 }
43824393
4383 - wfRunHooks( 'parserBeforerenderImageGallery', array( &$this, &$ig ) );
 4394+ wfRunHooks( 'BeforeParserrenderImageGallery', array( &$this, &$ig ) );
43844395
43854396 $lines = explode( "\n", $text );
43864397 foreach ( $lines as $line ) {
@@ -4529,7 +4540,7 @@
45304541 $alt = Sanitizer::stripAllTags( $alt );
45314542
45324543 # Give extensions a chance to select the file revision for us
4533 - $link = $skip = $time = false;
 4544+ $skip = $time = false;
45344545 wfRunHooks( 'BeforeParserMakeImageLinkObj', array( &$this, &$nt, &$skip, &$time ) );
45354546
45364547 # Linker does the rest
Index: branches/phase3_rev_deleted/includes/Skin.php
@@ -300,7 +300,7 @@
301301
302302 $ns = $wgTitle->getNamespace();
303303 $nsname = isset( $wgCanonicalNamespaceNames[ $ns ] ) ? $wgCanonicalNamespaceNames[ $ns ] : $wgTitle->getNsText();
304 -
 304+
305305 $vars = array(
306306 'skin' => $data['skinname'],
307307 'stylepath' => $wgStylePath,
@@ -313,6 +313,8 @@
314314 'wgPageName' => $wgTitle->getPrefixedDBKey(),
315315 'wgTitle' => $wgTitle->getText(),
316316 'wgAction' => $wgRequest->getText( 'action', 'view' ),
 317+ 'wgRestrictionEdit' => $wgTitle->getRestrictions( 'edit' ),
 318+ 'wgRestrictionMove' => $wgTitle->getRestrictions( 'move' ),
317319 'wgArticleId' => $wgTitle->getArticleId(),
318320 'wgIsArticle' => $wgOut->isArticle(),
319321 'wgUserName' => $wgUser->isAnon() ? NULL : $wgUser->getName(),
@@ -386,7 +388,8 @@
387389 function getUserStylesheet() {
388390 global $wgStylePath, $wgRequest, $wgContLang, $wgSquidMaxage, $wgStyleVersion;
389391 $sheet = $this->getStylesheet();
390 - $s = "@import \"$wgStylePath/common/common.css?$wgStyleVersion\";\n";
 392+ $s = "@import \"$wgStylePath/common/shared.css?$wgStyleVersion\";\n";
 393+ $s .= "@import \"$wgStylePath/common/oldshared.css?$wgStyleVersion\";\n";
391394 $s .= "@import \"$wgStylePath/$sheet?$wgStyleVersion\";\n";
392395 if($wgContLang->isRTL()) $s .= "@import \"$wgStylePath/common/common_rtl.css?$wgStyleVersion\";\n";
393396
Index: branches/phase3_rev_deleted/includes/ChangesList.php
@@ -557,7 +557,7 @@
558558 $r .= ' '.$this->recentChangesFlags( $isnew, false, $unpatrolled, '&nbsp;', $bot );
559559
560560 # Timestamp
561 - $r .= ' '.$block[0]->timestamp.'&nbsp;&nbsp;</td><td>';
 561+ $r .= '&nbsp;'.$block[0]->timestamp.'&nbsp;&nbsp;</td><td>';
562562
563563 # Article link
564564 if ( $namehidden )
Index: branches/phase3_rev_deleted/includes/SpecialUndelete.php
@@ -532,8 +532,8 @@
533533 $this->mTargetObj = NULL;
534534 }
535535 if( $this->mRestore ) {
536 - $this->mFileTimestamp = $request->getInt('imgrestorepoint');
537 - $this->mPageTimestamp = $request->getInt('restorepoint');
 536+ $this->mFileTimestamp = $request->getVal('imgrestorepoint');
 537+ $this->mPageTimestamp = $request->getVal('restorepoint');
538538 }
539539 $this->preCacheMessages();
540540 }
@@ -811,6 +811,8 @@
812812 } else {
813813 $wgOut->setPagetitle( wfMsg( 'viewdeletedpage' ) );
814814 }
 815+
 816+ $wgOut->addWikiText( wfMsgHtml( 'undeletepagetitle', $this->mTargetObj->getPrefixedText()) );
815817
816818 $archive = new PageArchive( $this->mTargetObj );
817819
@@ -847,24 +849,6 @@
848850 $wgOut->addHtml( $top );
849851 }
850852
851 - # Show relevant lines from the deletion log:
852 - $wgOut->addHTML( "<h2>" . htmlspecialchars( LogPage::logName( 'delete' ) ) . "</h2>\n" );
853 - $logViewer = new LogViewer(
854 - new LogReader(
855 - new FauxRequest(
856 - array( 'page' => $this->mTargetObj->getPrefixedText(),
857 - 'type' => 'delete' ) ) ) );
858 - $logViewer->showList( $wgOut );
859 - # Show relevant lines from the oversight log if user is allowed to see it:
860 - if( $wgUser->isAllowed( 'oversight' ) ) {
861 - $wgOut->addHTML( "<h2>" . htmlspecialchars( LogPage::logName( 'oversight' ) ) . "</h2>\n" );
862 - $logViewer = new LogViewer(
863 - new LogReader(
864 - new FauxRequest(
865 - array( 'page' => $this->mTargetObj->getPrefixedText(),
866 - 'type' => 'oversight' ) ) ) );
867 - $logViewer->showList( $wgOut );
868 - }
869853 if( $this->mAllowed && ( $haveRevisions || $haveFiles ) ) {
870854 # Format the user-visible controls (comment field, submission button)
871855 # in a nice little table
@@ -945,6 +929,25 @@
946930 $wgOut->addHTML( "</ul>" );
947931 }
948932
 933+ # Show relevant lines from the deletion log:
 934+ $wgOut->addHTML( "<h2>" . htmlspecialchars( LogPage::logName( 'delete' ) ) . "</h2>\n" );
 935+ $logViewer = new LogViewer(
 936+ new LogReader(
 937+ new FauxRequest(
 938+ array( 'page' => $this->mTargetObj->getPrefixedText(),
 939+ 'type' => 'delete' ) ) ) );
 940+ $logViewer->showList( $wgOut );
 941+ # Show relevant lines from the oversight log if user is allowed to see it:
 942+ if( $wgUser->isAllowed( 'oversight' ) ) {
 943+ $wgOut->addHTML( "<h2>" . htmlspecialchars( LogPage::logName( 'oversight' ) ) . "</h2>\n" );
 944+ $logViewer = new LogViewer(
 945+ new LogReader(
 946+ new FauxRequest(
 947+ array( 'page' => $this->mTargetObj->getPrefixedText(),
 948+ 'type' => 'oversight' ) ) ) );
 949+ $logViewer->showList( $wgOut );
 950+ }
 951+
949952 if( $this->mAllowed ) {
950953 # Slip in the hidden controls here
951954 $misc = wfHidden( 'target', $this->mTarget );
@@ -1193,9 +1196,10 @@
11941197 # Give some pointers to make (last) links
11951198 $this->mForm->prevId = array();
11961199 while( $row = $this->mResult->fetchObject() ) {
1197 - $rev_id = isset($rev_id) ? $rev_id : $row->ar_rev_id;
11981200 $batch->addObj( Title::makeTitleSafe( NS_USER, $row->ar_user_text ) );
11991201 $batch->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->ar_user_text ) );
 1202+
 1203+ $rev_id = isset($rev_id) ? $rev_id : $row->ar_rev_id;
12001204 if( $rev_id > $row->ar_rev_id )
12011205 $this->mForm->prevId[$rev_id] = $row->ar_rev_id;
12021206 else if( $rev_id < $row->ar_rev_id )
Index: branches/phase3_rev_deleted/includes/SpecialNewpages.php
@@ -36,12 +36,19 @@
3737 }
3838 }
3939
 40+ private function makeNamespaceWhere() {
 41+ return $this->namespace !== 'all'
 42+ ? ' AND rc_namespace = ' . intval( $this->namespace )
 43+ : '';
 44+ }
 45+
4046 function getSQL() {
4147 global $wgUser, $wgUseRCPatrol;
4248 $usepatrol = ( $wgUseRCPatrol && $wgUser->isAllowed( 'patrol' ) ) ? 1 : 0;
4349 $dbr = wfGetDB( DB_SLAVE );
4450 list( $recentchanges, $page ) = $dbr->tableNamesN( 'recentchanges', 'page' );
4551
 52+ $nsfilter = $this->makeNamespaceWhere();
4653 $uwhere = $this->makeUserWhere( $dbr );
4754
4855 # FIXME: text will break with compression
@@ -62,7 +69,8 @@
6370 page_latest as rev_id
6471 FROM $recentchanges,$page
6572 WHERE rc_cur_id=page_id AND rc_new=1
66 - AND rc_namespace=" . $this->namespace . " AND page_is_redirect=0
 73+ {$nsfilter}
 74+ AND page_is_redirect = 0
6775 {$uwhere}";
6876 }
6977
@@ -134,7 +142,7 @@
135143 $form = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $self->getLocalUrl() ) );
136144 # Namespace selector
137145 $form .= '<table><tr><td align="right">' . Xml::label( wfMsg( 'namespace' ), 'namespace' ) . '</td>';
138 - $form .= '<td>' . Xml::namespaceSelector( $this->namespace ) . '</td></tr>';
 146+ $form .= '<td>' . Xml::namespaceSelector( $this->namespace, 'all' ) . '</td></tr>';
139147 # Username filter
140148 $form .= '<tr><td align="right">' . Xml::label( wfMsg( 'newpages-username' ), 'mw-np-username' ) . '</td>';
141149 $form .= '<td>' . Xml::input( 'username', 30, $this->username, array( 'id' => 'mw-np-username' ) ) . '</td></tr>';
@@ -186,7 +194,7 @@
187195 }
188196 }
189197 } else {
190 - if( $ns = $wgRequest->getInt( 'namespace', 0 ) )
 198+ if( $ns = $wgRequest->getText( 'namespace', NS_MAIN ) )
191199 $namespace = $ns;
192200 if( $un = $wgRequest->getText( 'username' ) )
193201 $username = $un;
Index: branches/phase3_rev_deleted/includes/BagOStuff.php
@@ -172,7 +172,7 @@
173173 */
174174 var $bag;
175175
176 - function HashBagOStuff() {
 176+ function __construct() {
177177 $this->bag = array();
178178 }
179179
@@ -222,7 +222,7 @@
223223 var $table;
224224 var $lastexpireall = 0;
225225
226 - function SqlBagOStuff($tablename = 'objectcache') {
 226+ function __construct($tablename = 'objectcache') {
227227 $this->table = $tablename;
228228 }
229229
@@ -253,6 +253,9 @@
254254 }
255255
256256 function set($key,$value,$exptime=0) {
 257+ if ( wfReadOnly() ) {
 258+ return false;
 259+ }
257260 $exptime = intval($exptime);
258261 if($exptime < 0) $exptime = 0;
259262 if($exptime == 0) {
@@ -272,6 +275,9 @@
273276 }
274277
275278 function delete($key,$time=0) {
 279+ if ( wfReadOnly() ) {
 280+ return false;
 281+ }
276282 $this->_query(
277283 "DELETE FROM $0 WHERE keyname='$1'", $key );
278284 return true; /* ? */
@@ -339,12 +345,18 @@
340346
341347 function expireall() {
342348 /* Remove any items that have expired */
 349+ if ( wfReadOnly() ) {
 350+ return false;
 351+ }
343352 $now = $this->_fromunixtime( time() );
344353 $this->_query( "DELETE FROM $0 WHERE exptime < '$now'" );
345354 }
346355
347356 function deleteall() {
348357 /* Clear *all* items from cache table */
 358+ if ( wfReadOnly() ) {
 359+ return false;
 360+ }
349361 $this->_query( "DELETE FROM $0" );
350362 }
351363
@@ -553,6 +565,52 @@
554566 }
555567
556568 /**
 569+ * Wrapper for XCache object caching functions; identical interface
 570+ * to the APC wrapper
 571+ */
 572+class XCacheBagOStuff extends APCBagOStuff {
 573+
 574+ /**
 575+ * Get a value from the XCache object cache
 576+ *
 577+ * @param string $key Cache key
 578+ * @return mixed
 579+ */
 580+ public function get( $key ) {
 581+ $val = xcache_get( $key );
 582+ if( is_string( $val ) )
 583+ $val = unserialize( $val );
 584+ return $val;
 585+ }
 586+
 587+ /**
 588+ * Store a value in the XCache object cache
 589+ *
 590+ * @param string $key Cache key
 591+ * @param mixed $value Object to store
 592+ * @param int $expire Expiration time
 593+ * @return bool
 594+ */
 595+ public function set( $key, $value, $expire = 0 ) {
 596+ xcache_set( $key, serialize( $value ), $expire );
 597+ return true;
 598+ }
 599+
 600+ /**
 601+ * Remove a value from the XCache object cache
 602+ *
 603+ * @param string $key Cache key
 604+ * @param int $time Not used in this implementation
 605+ * @return bool
 606+ */
 607+ public function delete( $key, $time = 0 ) {
 608+ xcache_unset( $key );
 609+ return true;
 610+ }
 611+
 612+}
 613+
 614+/**
557615 * @todo document
558616 */
559617 class DBABagOStuff extends BagOStuff {
Index: branches/phase3_rev_deleted/includes/SpecialBlockip.php
@@ -43,6 +43,7 @@
4444 */
4545 class IPBlockForm {
4646 var $BlockAddress, $BlockExpiry, $BlockReason;
 47+# var $BlockEmail;
4748
4849 function IPBlockForm( $par ) {
4950 global $wgRequest, $wgUser;
@@ -60,6 +61,7 @@
6162 $this->BlockAnonOnly = $wgRequest->getBool( 'wpAnonOnly', $byDefault );
6263 $this->BlockCreateAccount = $wgRequest->getBool( 'wpCreateAccount', $byDefault );
6364 $this->BlockEnableAutoblock = $wgRequest->getBool( 'wpEnableAutoblock', $byDefault );
 65+ $this->BlockEmail = $wgRequest->getBool( 'wpEmailBan', false );
6466 # Re-check user's rights to hide names, very serious, defaults to 0
6567 $this->BlockHideName = ( $wgRequest->getBool( 'wpHideName', 0 ) && $wgUser->isAllowed( 'hideuser' ) ) ? 1 : 0;
6668 }
@@ -225,10 +227,25 @@
226228 </td>
227229 </tr>
228230 ");
 231+
 232+ global $wgSysopEmailBans;
 233+ if ( $wgSysopEmailBans && $wgUser->isAllowed( 'blockemail' ) ) {
 234+ $wgOut->addHTML("
 235+ <tr>
 236+ <td>&nbsp;</td>
 237+ <td>
 238+ " . wfCheckLabel( wfMsgHtml( 'ipbemailban' ),
 239+ 'wpEmailBan', 'wpEmailBan', $this->BlockEmail,
 240+ array( 'tabindex' => '10' )) . "
 241+ </td>
 242+ </tr>
 243+ ");
 244+ }
 245+
229246 // Allow some users to hide name from block log, blocklist and listusers
230247 if ( $wgUser->isAllowed( 'hideuser' ) ) {
231248 $wgOut->addHTML("
232 - <tr>
 249+ <tr id='wpEnableEmailBan'>
233250 <td>&nbsp;</td>
234251 <td>
235252 " . wfCheckLabel( wfMsgHtml( 'ipbhidename' ),
@@ -238,12 +255,13 @@
239256 </tr>
240257 ");
241258 }
 259+
242260 $wgOut->addHTML("
243261 <tr>
244262 <td style='padding-top: 1em'>&nbsp;</td>
245263 <td style='padding-top: 1em'>
246264 " . Xml::submitButton( wfMsg( 'ipbsubmit' ),
247 - array( 'name' => 'wpBlock', 'tabindex' => '10' ) ) . "
 265+ array( 'name' => 'wpBlock', 'tabindex' => '11' ) ) . "
248266 </td>
249267 </tr>
250268 </table>" .
@@ -356,10 +374,10 @@
357375
358376 # Create block
359377 # Note: for a user block, ipb_address is only for display purposes
360 -
361378 $block = new Block( $this->BlockAddress, $userId, $wgUser->getID(),
362379 $reasonstr, wfTimestampNow(), 0, $expiry, $this->BlockAnonOnly,
363 - $this->BlockCreateAccount, $this->BlockEnableAutoblock, $this->BlockHideName);
 380+ $this->BlockCreateAccount, $this->BlockEnableAutoblock, $this->BlockHideName,
 381+ $this->BlockEmail);
364382
365383 if (wfRunHooks('BlockIp', array(&$block, &$wgUser))) {
366384
@@ -420,6 +438,8 @@
421439 $flags[] = 'nocreate';
422440 if( !$this->BlockEnableAutoblock )
423441 $flags[] = 'noautoblock';
 442+ if ( $this->BlockEmail )
 443+ $flags[] = 'noemail';
424444 return implode( ',', $flags );
425445 }
426446
Index: branches/phase3_rev_deleted/includes/Math.php
@@ -157,8 +157,8 @@
158158 $dbw = wfGetDB( DB_MASTER );
159159 $dbw->replace( 'math', array( 'math_inputhash' ),
160160 array(
161 - 'math_inputhash' => $md5_sql,
162 - 'math_outputhash' => $outmd5_sql,
 161+ 'math_inputhash' => $dbw->encodeBlob($md5_sql),
 162+ 'math_outputhash' => $dbw->encodeBlob($outmd5_sql),
163163 'math_html_conservativeness' => $this->conservativeness,
164164 'math_html' => $this->html,
165165 'math_mathml' => $this->mathml,
@@ -186,13 +186,13 @@
187187 $dbr = wfGetDB( DB_SLAVE );
188188 $rpage = $dbr->selectRow( 'math',
189189 array( 'math_outputhash','math_html_conservativeness','math_html','math_mathml' ),
190 - array( 'math_inputhash' => pack("H32", $this->md5)), # Binary packed, not hex
 190+ array( 'math_inputhash' => $dbr->encodeBlob(pack("H32", $this->md5))), # Binary packed, not hex
191191 $fname
192192 );
193193
194194 if( $rpage !== false ) {
195195 # Tailing 0x20s can get dropped by the database, add it back on if necessary:
196 - $xhash = unpack( 'H32md5', $rpage->math_outputhash . " " );
 196+ $xhash = unpack( 'H32md5', $dbr->decodeBlob($rpage->math_outputhash) . " " );
197197 $this->hash = $xhash ['md5'];
198198
199199 $this->conservativeness = $rpage->math_html_conservativeness;
Index: branches/phase3_rev_deleted/includes/OutputPage.php
@@ -792,7 +792,11 @@
793793 $msg = 'blockedtext';
794794 }
795795
796 - $this->addWikiText( wfMsg( $msg, $link, $reason, $ip, $name, $blockid, $blockExpiry ) );
 796+ /* $ip returns who *is* being blocked, $intended contains who was meant to be blocked.
 797+ * This could be a username, an ip range, or a single ip. */
 798+ $intended = $wgUser->mBlock->mAddress;
 799+
 800+ $this->addWikiText( wfMsg( $msg, $link, $reason, $ip, $name, $blockid, $blockExpiry, $intended ) );
797801
798802 # Don't auto-return to special pages
799803 if( $return ) {
Index: branches/phase3_rev_deleted/includes/SpecialSpecialpages.php
@@ -17,7 +17,10 @@
1818 wfSpecialSpecialpages_gen( SpecialPage::getRegularPages(), 'spheading', $sk, false );
1919
2020 /** Restricted special pages */
21 - wfSpecialSpecialpages_gen( SpecialPage::getRestrictedPages(), 'restrictedpheading', $sk, true );
 21+ wfSpecialSpecialpages_gen( SpecialPage::getRestrictedPages(), 'restrictedpheading', $sk, false );
 22+
 23+ /** Restricted logs */
 24+ wfSpecialSpecialpages_gen( SpecialPage::getRestrictedLogs(), 'restrictedlheading', $sk, true );
2225 }
2326
2427 /**
@@ -25,10 +28,10 @@
2629 * @param $pages the list of pages
2730 * @param $heading header to be used
2831 * @param $sk skin object ???
29 - * @param $restricted, restricted pages or not
 32+ * @param $islog, is this for a list of log types?
3033 */
31 -function wfSpecialSpecialpages_gen($pages,$heading,$sk,$restricted) {
32 - global $wgOut, $wgUser, $wgSortSpecialPages, $wgLogRestrictions, $wgLogNames;
 34+function wfSpecialSpecialpages_gen( $pages, $heading, $sk, $islog=false ) {
 35+ global $wgOut, $wgUser, $wgSortSpecialPages;
3336
3437 if( count( $pages ) == 0 ) {
3538 # Yeah, that was pointless. Thanks for coming.
@@ -37,19 +40,12 @@
3841
3942 /** Put them into a sortable array */
4043 $sortedPages = array();
41 - foreach ( $pages as $page ) {
42 - if ( $page->isListed() ) {
43 - $sortedPages[$page->getDescription()] = $page->getTitle();
44 - }
45 - }
46 -
47 - # Add private logs
48 - if ( $restricted && isset($wgLogRestrictions) ) {
49 - foreach ( $wgLogRestrictions as $type => $restriction ) {
50 - $page = SpecialPage::getTitleFor( 'Log', $type );
51 - if ( $restriction != '' && $wgUser->isAllowed( $restriction ) ) {
52 - $name = wfMsgHtml( $wgLogNames[$type] );
53 - $sortedPages[$name] = $page;
 44+ if( $islog ) {
 45+ $sortedPages = $pages;
 46+ } else {
 47+ foreach ( $pages as $page ) {
 48+ if ( $page->isListed() ) {
 49+ $sortedPages[$page->getDescription()] = $page->getTitle();
5450 }
5551 }
5652 }
Index: branches/phase3_rev_deleted/includes/ImageGallery.php
@@ -147,6 +147,10 @@
148148 * @param $html String: Additional HTML text to be shown. The name and size of the image are always shown.
149149 */
150150 function insert( $title, $html='' ) {
 151+ if ( $title instanceof File ) {
 152+ // Old calling convention
 153+ $title = $title->getTitle();
 154+ }
151155 array_unshift( $this->mImages, array( &$title, $html ) );
152156 }
153157
Index: branches/phase3_rev_deleted/includes/DefaultSettings.php
@@ -27,7 +27,7 @@
2828 * Create a site configuration object
2929 * Not used for much in a default install
3030 */
31 -require_once( 'includes/SiteConfiguration.php' );
 31+require_once( "$IP/includes/SiteConfiguration.php" );
3232 $wgConf = new SiteConfiguration;
3333
3434 /** MediaWiki version number */
@@ -209,6 +209,10 @@
210210 * thumbScriptUrl The URL for thumb.php (optional, not recommended)
211211 * transformVia404 Whether to skip media file transformation on parse and rely on a 404
212212 * handler instead.
 213+ * initialCapital Equivalent to $wgCapitalLinks, determines whether filenames implicitly
 214+ * start with a capital letter. The current implementation may give incorrect
 215+ * description page links when the local $wgCapitalLinks and initialCapital
 216+ * are mismatched.
213217 *
214218 * These settings describe a foreign MediaWiki installation. They are optional, and will be ignored
215219 * for local repositories:
@@ -310,34 +314,34 @@
311315 *
312316 * @global array $wgAntivirusSetup
313317 */
314 -$wgAntivirusSetup= array(
 318+$wgAntivirusSetup = array(
315319
316320 #setup for clamav
317321 'clamav' => array (
318322 'command' => "clamscan --no-summary ",
319323
320 - 'codemap'=> array (
321 - "0"=> AV_NO_VIRUS, #no virus
322 - "1"=> AV_VIRUS_FOUND, #virus found
323 - "52"=> AV_SCAN_ABORTED, #unsupported file format (probably imune)
324 - "*"=> AV_SCAN_FAILED, #else scan failed
 324+ 'codemap' => array (
 325+ "0" => AV_NO_VIRUS, # no virus
 326+ "1" => AV_VIRUS_FOUND, # virus found
 327+ "52" => AV_SCAN_ABORTED, # unsupported file format (probably imune)
 328+ "*" => AV_SCAN_FAILED, # else scan failed
325329 ),
326330
327 - 'messagepattern'=> '/.*?:(.*)/sim',
 331+ 'messagepattern' => '/.*?:(.*)/sim',
328332 ),
329333
330334 #setup for f-prot
331335 'f-prot' => array (
332336 'command' => "f-prot ",
333337
334 - 'codemap'=> array (
335 - "0"=> AV_NO_VIRUS, #no virus
336 - "3"=> AV_VIRUS_FOUND, #virus found
337 - "6"=> AV_VIRUS_FOUND, #virus found
338 - "*"=> AV_SCAN_FAILED, #else scan failed
 338+ 'codemap' => array (
 339+ "0" => AV_NO_VIRUS, # no virus
 340+ "3" => AV_VIRUS_FOUND, # virus found
 341+ "6" => AV_VIRUS_FOUND, # virus found
 342+ "*" => AV_SCAN_FAILED, # else scan failed
339343 ),
340344
341 - 'messagepattern'=> '/.*?Infection:(.*)$/m',
 345+ 'messagepattern' => '/.*?Infection:(.*)$/m',
342346 ),
343347 );
344348
@@ -859,6 +863,7 @@
860864
861865 $wgShowIPinHeader = true; # For non-logged in users
862866 $wgMaxNameChars = 255; # Maximum number of bytes in username
 867+$wgMaxSigChars = 255; # Maximum number of bytes in signature
863868 $wgMaxArticleSize = 2048; # Maximum article size in kilobytes
864869
865870 $wgExtraSubtitle = '';
@@ -973,9 +978,10 @@
974979
975980 # Basic user rights and block settings
976981 $wgSysopUserBans = true; # Allow sysops to ban logged-in users
977 -$wgSysopRangeBans = true; # Allow sysops to ban IP ranges
978 -$wgAutoblockExpiry = 86400; # Number of seconds before autoblock entries expire
 982+$wgSysopRangeBans = true; # Allow sysops to ban IP ranges
 983+$wgAutoblockExpiry = 86400; # Number of seconds before autoblock entries expire
979984 $wgBlockAllowsUTEdit = false; # Blocks allow users to edit their own user talk page
 985+$wgSysopEmailBans = true; # Allow sysops to ban users from accessing Emailuser
980986
981987 # Pages anonymous user may see as an array, e.g.:
982988 # array ( "Main Page", "Special:Userlogin", "Wikipedia:Help");
@@ -1064,6 +1070,7 @@
10651071 $wgGroupPermissions['sysop']['upload_by_url'] = true;
10661072 $wgGroupPermissions['sysop']['ipblock-exempt'] = true;
10671073 $wgGroupPermissions['sysop']['deleterevision'] = true;
 1074+$wgGroupPermissions['sysop']['blockemail'] = true;
10681075
10691076 // Permission to change users' group assignments
10701077 $wgGroupPermissions['bureaucrat']['userrights'] = true;
@@ -1093,6 +1100,10 @@
10941101 /**
10951102 * Set of permission keys that can be selected via action=protect.
10961103 * 'autoconfirm' allows all registerd users if $wgAutoConfirmAge is 0.
 1104+ *
 1105+ * You can add a new protection level that requires a specific
 1106+ * permission by manipulating this array. The ordering of elements
 1107+ * dictates the order on the protection form's lists.
10971108 */
10981109 $wgRestrictionLevels = array( '', 'autoconfirmed', 'sysop' );
10991110
@@ -1183,7 +1194,7 @@
11841195 * to ensure that client-side caches don't keep obsolete copies of global
11851196 * styles.
11861197 */
1187 -$wgStyleVersion = '73';
 1198+$wgStyleVersion = '76';
11881199
11891200
11901201 # Server-side caching:
@@ -1416,6 +1427,13 @@
14171428 /**
14181429 * Show EXIF data, on by default if available.
14191430 * Requires PHP's EXIF extension: http://www.php.net/manual/en/ref.exif.php
 1431+ *
 1432+ * NOTE FOR WINDOWS USERS:
 1433+ * To enable EXIF functions, add the folloing lines to the
 1434+ * "Windows extensions" section of php.ini:
 1435+ *
 1436+ * extension=extensions/php_mbstring.dll
 1437+ * extension=extensions/php_exif.dll
14201438 */
14211439 $wgShowEXIF = function_exists( 'exif_read_data' );
14221440
@@ -1470,7 +1488,7 @@
14711489 /** Files with these extensions will never be allowed as uploads. */
14721490 $wgFileBlacklist = array(
14731491 # HTML may contain cookie-stealing JavaScript and web bugs
1474 - 'html', 'htm', 'js', 'jsb',
 1492+ 'html', 'htm', 'js', 'jsb', 'mhtml', 'mht',
14751493 # PHP scripts may execute arbitrary code on the server
14761494 'php', 'phtml', 'php3', 'php4', 'php5', 'phps',
14771495 # Other types that may be interpreted by some servers
@@ -1526,10 +1544,15 @@
15271545 NS_MAIN => true,
15281546 );
15291547
1530 -/** If set, a bold ugly notice will show up at the top of every page. */
 1548+/**
 1549+ * Site notice shown at the top of each page
 1550+ *
 1551+ * This message can contain wiki text, and can also be set through the
 1552+ * MediaWiki:Sitenotice page. You can also provide a separate message for
 1553+ * logged-out users using the MediaWiki:Anonnotice page.
 1554+ */
15311555 $wgSiteNotice = '';
15321556
1533 -
15341557 #
15351558 # Images settings
15361559 #
@@ -2180,7 +2203,7 @@
21812204 * Extensions with custom log types may add to this array.
21822205 */
21832206 $wgLogNames = array(
2184 - '' => 'log',
 2207+ '' => 'all-logs-page',
21852208 'block' => 'blocklogpage',
21862209 'protect' => 'protectlogpage',
21872210 'rights' => 'rightslog',
@@ -2221,6 +2244,7 @@
22222245 'block/block' => 'blocklogentry',
22232246 'block/unblock' => 'unblocklogentry',
22242247 'protect/protect' => 'protectedarticle',
 2248+ 'protect/modify' => 'modifiedarticleprotection',
22252249 'protect/unprotect' => 'unprotectedarticle',
22262250 'rights/rights' => 'rightslogentry',
22272251 'delete/delete' => 'deletedarticle',
@@ -2291,6 +2315,16 @@
22922316 $wgNamespaceRobotPolicies = array();
22932317
22942318 /**
 2319+ * Robot policies per article.
 2320+ * These override the per-namespace robot policies.
 2321+ * Must be in the form of an array where the key part is a properly
 2322+ * canonicalised text form title and the value is a robot policy.
 2323+ * Example:
 2324+ * $wgArticleRobotPolicies = array( 'Main Page' => 'noindex' );
 2325+ */
 2326+$wgArticleRobotPolicies = array();
 2327+
 2328+/**
22952329 * Specifies the minimal length of a user password. If set to
22962330 * 0, empty passwords are allowed.
22972331 */
Index: branches/phase3_rev_deleted/includes/ImagePage.php
@@ -274,7 +274,7 @@
275275 if ( $page > 1 ) {
276276 $label = $wgOut->parse( wfMsg( 'imgmultipageprev' ), false );
277277 $link = $sk->makeKnownLinkObj( $this->mTitle, $label, 'page='. ($page-1) );
278 - $thumb1 = $sk->makeThumbLinkObj( $this->img, $link, $label, 'none',
 278+ $thumb1 = $sk->makeThumbLinkObj( $this->mTitle, $this->img, $link, $label, 'none',
279279 array( 'page' => $page - 1 ) );
280280 } else {
281281 $thumb1 = '';
@@ -283,7 +283,7 @@
284284 if ( $page < $count ) {
285285 $label = wfMsg( 'imgmultipagenext' );
286286 $link = $sk->makeKnownLinkObj( $this->mTitle, $label, 'page='. ($page+1) );
287 - $thumb2 = $sk->makeThumbLinkObj( $this->img, $link, $label, 'none',
 287+ $thumb2 = $sk->makeThumbLinkObj( $this->mTitle, $this->img, $link, $label, 'none',
288288 array( 'page' => $page + 1 ) );
289289 } else {
290290 $thumb2 = '';
@@ -503,6 +503,12 @@
504504 {
505505 global $wgUser, $wgOut, $wgRequest;
506506
 507+ if ( !$this->img->exists() || !$this->img->isLocal() ) {
 508+ # Use standard article deletion
 509+ Article::delete();
 510+ return;
 511+ }
 512+
507513 $confirm = $wgRequest->wasPosted();
508514 $reason = $wgRequest->getVal( 'wpReason' );
509515 $image = $wgRequest->getVal( 'image' );
@@ -536,7 +542,7 @@
537543 # Deleting old images doesn't require confirmation
538544 if ( !is_null( $oldimage ) || $confirm ) {
539545 if( $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ), $oldimage ) ) {
540 - $this->doDelete( $reason, $suppress );
 546+ $this->doDeleteImage( $reason );
541547 } else {
542548 $wgOut->showFatalError( wfMsg( 'sessionfailure' ) );
543549 }
@@ -555,9 +561,12 @@
556562
557563 /*
558564 * Delete an image.
 565+ * Called doDeleteImage() not doDelete() so that Article::delete() doesn't
 566+ * call back to here.
 567+ *
559568 * @param $reason User provided reason for deletion.
560569 */
561 - function doDelete( $reason, $suppress=false ) {
 570+ function doDeleteImage( $reason ) {
562571 global $wgOut, $wgRequest;
563572
564573 $oldimage = $wgRequest->getVal( 'oldimage' );
@@ -644,7 +653,7 @@
645654 $wgOut->showErrorPage( 'uploadnologin', 'uploadnologintext' );
646655 return;
647656 }
648 - if ( ! $this->mTitle->userCan( 'edit' ) ) {
 657+ if ( !$this->mTitle->userCan( 'edit' ) || !$this->mTitle->userCan( 'upload' ) ) {
649658 $wgOut->readOnlyPage( $this->getContent(), true );
650659 return;
651660 }
@@ -658,7 +667,8 @@
659668 }
660669
661670 $sourcePath = $this->img->getArchiveVirtualUrl( $oldimage );
662 - $result = $this->img->publish( $sourcePath );
 671+ $comment = wfMsg( "reverted" );
 672+ $result = $this->img->upload( $sourcePath, $comment, $comment );
663673
664674 if ( WikiError::isError( $result ) ) {
665675 $this->showError( $result );
@@ -753,7 +763,7 @@
754764 }
755765 } else {
756766 $url = htmlspecialchars( $this->img->getArchiveUrl( $img ) );
757 - if( $local && $wgUser->getID() != 0 && $wgTitle->userCan( 'edit' ) ) {
 767+ if( $local && $wgUser->getID() != 0 && $wgTitle->userCan( 'edit' ) && $wgTitle->userCan( 'upload' ) ) {
758768 # Revert link, for public files only
759769 if ( $deleted ) {
760770 $rlink = wfMsgHtml( 'revertimg' );
@@ -867,7 +877,7 @@
868878 if( ($bitfield & $field) == $field ) {
869879 // images
870880 global $wgUser;
871 - $permission = ( $bitfield & Image::DELETED_RESTRICTED ) == Image::DELETED_RESTRICTED
 881+ $permission = ( $bitfield & File::DELETED_RESTRICTED ) == File::DELETED_RESTRICTED
872882 ? 'hiderevision'
873883 : 'deleterevision';
874884 wfDebug( "Checking for $permission due to $field match on $bitfield\n" );
Index: branches/phase3_rev_deleted/includes/SpecialRevisiondelete.php
@@ -6,7 +6,7 @@
77 */
88
99 function wfSpecialRevisiondelete( $par = null ) {
10 - global $wgOut, $wgRequest;
 10+ global $wgOut, $wgRequest, $wgUser;
1111
1212 $target = $wgRequest->getText( 'target' );
1313 // Handle our many different possible input types
@@ -42,6 +42,25 @@
4343 } else if( $fileid || $image ) {
4444 $form->showImages( $wgRequest );
4545 }
 46+
 47+ # Show relevant lines from the deletion log:
 48+ $wgOut->addHTML( "<h2>" . htmlspecialchars( LogPage::logName( 'delete' ) ) . "</h2>\n" );
 49+ $logViewer = new LogViewer(
 50+ new LogReader(
 51+ new FauxRequest(
 52+ array( 'page' => $page->getPrefixedText(),
 53+ 'type' => 'delete' ) ) ) );
 54+ $logViewer->showList( $wgOut );
 55+ # Show relevant lines from the oversight log if user is allowed to see it:
 56+ if( $wgUser->isAllowed( 'oversight' ) ) {
 57+ $wgOut->addHTML( "<h2>" . htmlspecialchars( LogPage::logName( 'oversight' ) ) . "</h2>\n" );
 58+ $logViewer = new LogViewer(
 59+ new LogReader(
 60+ new FauxRequest(
 61+ array( 'page' => $page->getPrefixedText(),
 62+ 'type' => 'oversight' ) ) ) );
 63+ $logViewer->showList( $wgOut );
 64+ }
4665 }
4766
4867 /**
@@ -67,6 +86,7 @@
6887 // For reviewing deleted files
6988 if ( $file ) {
7089 $oimage = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName( $page, $file );
 90+ $oimage->load();
7191 // Check if user is allowed to see this file
7292 if( !$oimage->userCan(File::DELETED_FILE) ) {
7393 $wgOut->permissionRequired( 'hiderevision' );
@@ -99,7 +119,8 @@
100120 $hide_content_name = array( 'revdelete-hide-name', 'wpHideName', LogViewer::DELETED_ACTION );
101121 $this->deletetype='logid';
102122 }
103 - // Our checkbox messages depends one what we are doing
 123+ // Our checkbox messages depends one what we are doing,
 124+ // e.g. we don't hide "text" for logs or images
104125 $this->checks = array(
105126 $hide_content_name,
106127 array( 'revdelete-hide-comment', 'wpHideComment', Revision::DELETED_COMMENT ),
@@ -141,7 +162,7 @@
142163 $bitfields = 0;
143164 $wgOut->addHtml( "<ul>" );
144165 // Live revisions...
145 - if( $this->deletetype=='oldid') {
 166+ if( $this->deletetype=='oldid' ) {
146167 foreach( $this->revisions as $revid ) {
147168 $rev = Revision::newFromTitle( $this->page, $revid );
148169 // Hiding top revisison is bad
@@ -154,7 +175,7 @@
155176 $wgOut->permissionRequired( 'hiderevision' );
156177 return;
157178 }
158 - $UserAllowed=false;
 179+ $UserAllowed = false;
159180 }
160181 $wgOut->addHtml( $this->historyLine( $rev ) );
161182 $bitfields |= $rev->mDeleted;
@@ -173,7 +194,7 @@
174195 $wgOut->permissionRequired( 'hiderevision' );
175196 return;
176197 }
177 - $UserAllowed=false;
 198+ $UserAllowed = false;
178199 }
179200 $wgOut->addHtml( $this->historyLine( $rev ) );
180201 $bitfields |= $rev->mDeleted;
@@ -238,27 +259,55 @@
239260
240261 $bitfields = 0;
241262 $wgOut->addHtml( "<ul>" );
242 - // Live revisions...
 263+ // Live old revisions...
243264 if( $this->deletetype=='oldimage' ) {
 265+ $where = $filesObjs = array();
 266+ $dbr = wfGetDB( DB_SLAVE );
 267+ // Run through and pull all our data in one query
244268 foreach( $this->ofiles as $name ) {
245269 // Our image may be hidden, if so it's name is formated as <time>!<key>
246270 // Otherwise, it will be <time>!<image> and the URL only needs to pass the time
247271 $archivename = ( strpos($name,'!')==false ) ? $name.'!'.$this->page->getDbKey() : $name;
 272+ $where[] = $dbr->addQuotes($archivename);
 273+ }
 274+ $whereClause = 'oi_archive_name IN(' . implode(',',$where) . ')';
 275+ // Pull all of the requested images
 276+ $result = $dbr->select( 'oldimage', array('oi_archive_name', 'oi_size', 'oi_width', 'oi_height',
 277+ 'oi_description', 'oi_user', 'oi_user_text', 'oi_timestamp', 'oi_deleted'),
 278+ array( 'oi_name' => $this->page->getDbKey(), $whereClause ),
 279+ __METHOD__ );
 280+ while( $s = $dbr->fetchObject( $result ) ) {
 281+ $filesObjs[$s->oi_archive_name] = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName( $this->page, $archivename );
 282+ // Load in fields directly, weeee!
 283+ $filesObjs[$s->oi_archive_name]->size = $s->oi_size;
 284+ $filesObjs[$s->oi_archive_name]->width = $s->oi_width;
 285+ $filesObjs[$s->oi_archive_name]->height = $s->oi_height;
 286+ $filesObjs[$s->oi_archive_name]->description = $s->oi_description;
 287+ $filesObjs[$s->oi_archive_name]->user = $s->oi_user;
 288+ $filesObjs[$s->oi_archive_name]->userText = $s->oi_user_text;
 289+ $filesObjs[$s->oi_archive_name]->timestamp = $s->oi_timestamp;
 290+ $filesObjs[$s->oi_archive_name]->deleted = $s->oi_deleted;
 291+ }
 292+ // Check through our images
 293+ foreach( $this->ofiles as $name ) {
 294+ // Our image may be hidden, if so it's name is formated as <time>!<key>
 295+ // Otherwise, it will be <time>!<image> and the URL only needs to pass the time
 296+ $archivename = ( strpos($name,'!')==false ) ? $name.'!'.$this->page->getDbKey() : $name;
248297
249 - $oimage = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName( $this->page, $archivename );
250 - if( !$oimage->exists() ) {
 298+ if( !isset($filesObjs[$archivename]) ) {
251299 $wgOut->showErrorPage( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
252300 return;
253 - } else if( !$oimage->userCan(File::DELETED_RESTRICTED) ) {
 301+ } else if( !$filesObjs[$archivename]->userCan(File::DELETED_RESTRICTED) ) {
254302 // If a rev is hidden from sysops
255303 if( $action != 'submit' ) {
256304 $wgOut->permissionRequired( 'hiderevision' );
257305 return;
258306 }
259 - $UserAllowed=false;
 307+ $UserAllowed = false;
260308 }
261 - $wgOut->addHtml( $this->uploadLine( $oimage ) );
262 - $bitfields |= $oimage->deleted;
 309+ // Inject history info
 310+ $wgOut->addHtml( $this->uploadLine( $filesObjs[$archivename] ) );
 311+ $bitfields |= $filesObjs[$archivename]->deleted;
263312 }
264313 // Archived files...
265314 } else {
@@ -273,7 +322,7 @@
274323 $wgOut->permissionRequired( 'hiderevision' );
275324 return;
276325 }
277 - $UserAllowed=false;
 326+ $UserAllowed = false;
278327 }
279328 $wgOut->addHtml( $this->uploadLine( $file ) );
280329 $bitfields |= $file->deleted;
@@ -332,26 +381,26 @@
333382 global $wgOut, $wgUser, $action;
334383
335384 $UserAllowed = true;
336 - $wgOut->addWikiText( wfMsgExt( 'logdelete-selected', array('parsemag'), $this->page->getPrefixedText(), count($this->events) ) );
 385+ $wgOut->addWikiText( wfMsgExt( 'logdelete-selected', array('parsemag'),
 386+ $this->page->getPrefixedText(), count($this->events) ) );
337387
338388 $bitfields = 0;
339389 $wgOut->addHtml( "<ul>" );
340390 foreach( $this->events as $logid ) {
341 - $log = new LogViewer( $wgRequest );
342 - $event = LogReader::newFromTitle( $this->page, $logid );
 391+ $event = LogReader::newRowFromTitle( $this->page, $logid );
343392 // Don't hide from oversight log!!!
344393 if( !isset( $event ) || $event->log_type=='oversight' ) {
345394 $wgOut->showErrorPage( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
346395 return;
347 - } else if( !$log->userCan($event,Revision::DELETED_RESTRICTED) ) {
 396+ } else if( !LogViewer::userCan($event,Revision::DELETED_RESTRICTED) ) {
348397 // If an event is hidden from sysops
349398 if( $action != 'submit') {
350399 $wgOut->permissionRequired( 'hiderevision' );
351400 return;
352401 }
353 - $UserAllowed=false;
 402+ $UserAllowed = false;
354403 }
355 - $wgOut->addHtml( $this->logLine( $log, $event ) );
 404+ $wgOut->addHtml( $this->logLine( $event ) );
356405 $bitfields |= $event->log_deleted;
357406 }
358407 $wgOut->addHtml( "</ul>" );
@@ -430,7 +479,7 @@
431480 }
432481
433482 /**
434 - * @param OldLocalImage or ArchivedFile $file
 483+ * @param File $file
435484 * This can work for old or archived revisions
436485 * @returns string
437486 */
@@ -453,7 +502,7 @@
454503 if( !$file->userCan(File::DELETED_FILE) ) {
455504 $pageLink = $date;
456505 } else {
457 - $pageLink = $this->skin->makeKnownLinkObj( $wgTitle, $date, "target=$target&file=$file->mArchiveName" );
 506+ $pageLink = $this->skin->makeKnownLinkObj( $wgTitle, $date, "target=$target&file=$file->archive_name" );
458507 }
459508 $pageLink = '<span class="history-deleted">' . $pageLink . '</span>';
460509 # Regular files...
@@ -464,19 +513,18 @@
465514 }
466515
467516 $data = wfMsgHtml( 'widthheight',
468 - $wgContLang->formatNum( $file->width ),
469 - $wgContLang->formatNum( $file->height ) ) .
470 - ' (' . wfMsgHtml( 'nbytes', $wgContLang->formatNum( $file->size ) ) . ')';
 517+ $wgContLang->formatNum( $file->width ),
 518+ $wgContLang->formatNum( $file->height ) ) .
 519+ ' (' . wfMsgHtml( 'nbytes', $wgContLang->formatNum( $file->size ) ) . ')';
471520
472 - #return "<li> $pageLink " . $this->skin->fileUserLink( $file ) . " $data " . $this->skin->fileComment( $file ) . "$del</li>";
473 - return "<li> $pageLink $data $del</li>";
 521+ return "<li> $pageLink " . $this->fileUserLink( $file ) . " $data " . $this->fileComment( $file ) . "$del</li>";
474522 }
475523
476524 /**
477 - * @param Revision $rev
 525+ * @param Array $event row
478526 * @returns string
479527 */
480 - function logLine( $log, $event ) {
 528+ function logLine( $event ) {
481529 global $wgContLang;
482530
483531 $date = $wgContLang->timeanddate( $event->log_timestamp );
@@ -494,6 +542,68 @@
495543 }
496544
497545 /**
 546+ * Generate a user link if the current user is allowed to view it
 547+ * @param ArchivedFile $file
 548+ * @param $isPublic, bool, show only if all users can see it
 549+ * @return string HTML
 550+ */
 551+ function fileUserLink( $file, $isPublic = false ) {
 552+ if( $file->isDeleted( File::DELETED_USER ) && $isPublic ) {
 553+ $link = wfMsgHtml( 'rev-deleted-user' );
 554+ } else if( $file->userCan( File::DELETED_USER ) ) {
 555+ $link = $this->skin->userLink( $file->user, $file->userText );
 556+ } else {
 557+ $link = wfMsgHtml( 'rev-deleted-user' );
 558+ }
 559+ if( $file->isDeleted( File::DELETED_USER ) ) {
 560+ return '<span class="history-deleted">' . $link . '</span>';
 561+ }
 562+ return $link;
 563+ }
 564+
 565+ /**
 566+ * Generate a user tool link cluster if the current user is allowed to view it
 567+ * @param ArchivedFile $file
 568+ * @param $isPublic, bool, show only if all users can see it
 569+ * @return string HTML
 570+ */
 571+ function fileUserTools( $file, $isPublic = false ) {
 572+ if( $file->isDeleted( Revision::DELETED_USER ) && $isPublic ) {
 573+ $link = wfMsgHtml( 'rev-deleted-user' );
 574+ } else if( $file->userCan( Revision::DELETED_USER ) ) {
 575+ $link = $this->skin->userLink( $file->user, $file->userText ) .
 576+ $this->userToolLinks( $file->user, $file->userText );
 577+ } else {
 578+ $link = wfMsgHtml( 'rev-deleted-user' );
 579+ }
 580+ if( $file->isDeleted( Revision::DELETED_USER ) ) {
 581+ return '<span class="history-deleted">' . $link . '</span>';
 582+ }
 583+ return $link;
 584+ }
 585+
 586+ /**
 587+ * Wrap and format the given file's comment block, if the current
 588+ * user is allowed to view it.
 589+ *
 590+ * @param ArchivedFile $file
 591+ * @return string HTML
 592+ */
 593+ function fileComment( $file, $isPublic = false ) {
 594+ if( $file->isDeleted( File::DELETED_COMMENT ) && $isPublic ) {
 595+ $block = ' ' . wfMsgHtml( 'rev-deleted-comment' );
 596+ } else if( $file->userCan( File::DELETED_COMMENT ) ) {
 597+ $block = $this->skin->commentBlock( $file->description );
 598+ } else {
 599+ $block = ' ' . wfMsgHtml( 'rev-deleted-comment' );
 600+ }
 601+ if( $file->isDeleted( File::DELETED_COMMENT ) ) {
 602+ return "<span class=\"history-deleted\">$block</span>";
 603+ }
 604+ return $block;
 605+ }
 606+
 607+ /**
498608 * @param WebRequest $request
499609 */
500610 function submit( $request ) {
@@ -524,12 +634,19 @@
525635
526636 $title = Title::newFromURL( $target, true );
527637 $name = $title->makeName( $title->getNamespace(), $title->getText() );
528 -
 638+ # Give a link to the log for this page
529639 $logtitle = SpecialPage::getTitleFor( 'Log' );
530640 $loglink = $this->skin->makeKnownLinkObj( $logtitle, wfMsgHtml( 'viewpagelogs' ),
531 - wfArrayToCGI( array('page' => $name ) ) );
532 - $histlink = $this->skin->makeKnownLinkObj( $title, wfMsgHtml( 'revhistory' ),
533 - wfArrayToCGI( array('action' => 'history' ) ) );
 641+ wfArrayToCGI( array('page' => $name ) ) );
 642+ # Give a link to the page history
 643+ if( $type=='arid' ) {
 644+ $undelete = SpecialPage::getTitleFor( 'Undelete' );
 645+ $histlink = $this->skin->makeKnownLinkObj( $undelete, wfMsgHtml( 'revhistory' ),
 646+ wfArrayToCGI( array('target' => $title->getPrefixedText() ) ) );
 647+ } else {
 648+ $histlink = $this->skin->makeKnownLinkObj( $title, wfMsgHtml( 'revhistory' ),
 649+ wfArrayToCGI( array('action' => 'history' ) ) );
 650+ }
534651
535652 if( $title->getNamespace() > -1)
536653 $wgOut->setSubtitle( '<p>'.$histlink.' / '.$loglink.'</p>' );
@@ -537,10 +654,10 @@
538655 if( $type=='logid' ) {
539656 $wgOut->addWikiText( wfMsgHtml('logdelete-success', $target), false );
540657 $this->showEvents( $request );
541 - } else if( $type=='oldid' ) {
 658+ } else if( $type=='oldid' || $type=='arid' ) {
542659 $wgOut->addWikiText( wfMsgHtml('revdelete-success', $target), false );
543660 $this->showRevs( $request );
544 - } else if( $type=='arid' || $type=='fileid' ) {
 661+ } else if( $type=='fileid' ) {
545662 $undelete = SpecialPage::getTitleFor( 'Undelete' );
546663 # Redirect out, we already have the deleted history right there
547664 $wgOut->redirect( $undelete->escapeLocalUrl() . '/' . htmlspecialchars($target) );
@@ -568,6 +685,11 @@
569686
570687 function save( $bitfield, $reason, $title ) {
571688 $dbw = wfGetDB( DB_MASTER );
 689+
 690+ // Don't allow simply locking the interface for no reason
 691+ if( $bitfield == Revision::DELETED_RESTRICTED )
 692+ $bitfield = 0;
 693+
572694 $deleter = new RevisionDeleter( $dbw );
573695 // By this point, only one of the below should be set
574696 if( isset($this->revisions) ) {
@@ -602,16 +724,17 @@
603725 function setRevVisibility( $title, $items, $bitfield, $comment ) {
604726 global $wgOut;
605727
606 - $UserAllowedAll = true;
 728+ $userAllowedAll = $success = true;
607729 $pages_count = array();
608730 $pages_revIds = array();
609731 // To work!
610732 foreach( $items as $revid ) {
611733 $rev = Revision::newFromTitle( $title, $revid );
612734 if( !is_object($rev) || $rev->isCurrent() ) {
613 - return false;
 735+ $success = false;
 736+ continue; // Must exist
614737 } else if( !$rev->userCan(Revision::DELETED_RESTRICTED) ) {
615 - $UserAllowedAll=false;
 738+ $userAllowedAll=false;
616739 continue;
617740 }
618741 $pageid = $rev->getPage();
@@ -640,13 +763,13 @@
641764 }
642765 }
643766 // Where all revs allowed to be set?
644 - if( !$UserAllowedAll ) {
 767+ if( !$userAllowedAll ) {
645768 //FIXME: still might be confusing???
646769 $wgOut->permissionRequired( 'hiderevision' );
647770 return false;
648771 }
649772
650 - return true;
 773+ return $success;
651774 }
652775
653776 /**
@@ -658,7 +781,7 @@
659782 function setArchiveVisibility( $title, $items, $bitfield, $comment ) {
660783 global $wgOut;
661784
662 - $UserAllowedAll = true;
 785+ $userAllowedAll = $success = true;
663786 $count = 0;
664787 $Id_set = array();
665788 // To work!
@@ -666,9 +789,10 @@
667790 foreach( $items as $revid ) {
668791 $rev = $archive->getRevision( '', $revid );
669792 if( !is_object($rev) ) {
670 - return false;
 793+ $success = false;
 794+ continue; // Must exist
671795 } else if( !$rev->userCan(Revision::DELETED_RESTRICTED) ) {
672 - $UserAllowedAll=false;
 796+ $userAllowedAll=false;
673797 continue;
674798 }
675799 // Which revisions did we change anything about?
@@ -685,12 +809,12 @@
686810 $this->updateLog( $title, $count, $bitfield, $comment, $title, 'arid', $Id_set );
687811 }
688812 // Where all revs allowed to be set?
689 - if( !$UserAllowedAll ) {
 813+ if( !$userAllowedAll ) {
690814 $wgOut->permissionRequired( 'hiderevision' );
691815 return false;
692816 }
693817
694 - return true;
 818+ return $success;
695819 }
696820
697821 /**
@@ -702,7 +826,7 @@
703827 function setOldImgVisibility( $title, $items, $bitfield, $comment ) {
704828 global $wgOut;
705829
706 - $UserAllowedAll = true;
 830+ $userAllowedAll = $success = true;
707831 $count = 0;
708832 $set = array();
709833 // To work!
@@ -711,10 +835,12 @@
712836 // Otherwise, it will be <time>!<image> and the URL only needs to pass the time
713837 $archivename = ( strpos($name,'!')==false ) ? $name.'!'.$title->getDbKey() : $name;
714838 $oimage = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName( $title, $archivename );
715 - if( !$oimage->exists() ) {
716 - return false;
 839+ $oimage->load();
 840+ if( !$oimage->timestamp ) {
 841+ $success = false;
 842+ continue; // Must exist
717843 } else if( !$oimage->userCan(File::DELETED_RESTRICTED) ) {
718 - $UserAllowedAll=false;
 844+ $userAllowedAll=false;
719845 continue;
720846 }
721847
@@ -759,12 +885,12 @@
760886 $this->updateLog( $title, $count, $bitfield, $comment, $title, 'oldimage', $set );
761887 }
762888 // Where all revs allowed to be set?
763 - if( !$UserAllowedAll ) {
 889+ if( !$userAllowedAll ) {
764890 $wgOut->permissionRequired( 'hiderevision' );
765891 return false;
766892 }
767893
768 - return true;
 894+ return $success;
769895 }
770896
771897 /**
@@ -776,20 +902,21 @@
777903 function setArchFileVisibility( $title, $items, $bitfield, $comment ) {
778904 global $wgOut;
779905
780 - $UserAllowedAll = true;
 906+ $userAllowedAll = $success = true;
781907 $count = 0;
782908 $Id_set = array();
783909 // To work!
784910 foreach( $items as $fileid ) {
785911 $file = new ArchivedFile( $title, $fileid );
786912 if( !isset($file->id) ) {
787 - return false;
 913+ $success = false;
 914+ continue; // Must exist
788915 } else if( !$file->userCan(File::DELETED_RESTRICTED) ) {
789 - $UserAllowedAll=false;
 916+ $userAllowedAll=false;
790917 continue;
791918 }
792919 // Which revisions did we change anything about?
793 - if( $file->mDeleted != $bitfield ) {
 920+ if( $file->deleted != $bitfield ) {
794921 $Id_set[]=$fileid;
795922 $count++;
796923
@@ -802,12 +929,12 @@
803930 $this->updateLog( $title, $count, $bitfield, $comment, $title, 'fileid', $Id_set );
804931 }
805932 // Where all revs allowed to be set?
806 - if( !$UserAllowedAll ) {
 933+ if( !$userAllowedAll ) {
807934 $wgOut->permissionRequired( 'hiderevision' );
808935 return false;
809936 }
810937
811 - return true;
 938+ return $success;
812939 }
813940
814941 /**
@@ -819,17 +946,18 @@
820947 function setEventVisibility( $title, $items, $bitfield, $comment ) {
821948 global $wgOut;
822949
823 - $UserAllowedAll = true;
 950+ $userAllowedAll = $success = true;
824951 $logs_count = array();
825952 $logs_Ids = array();
826953 // To work!
827954 foreach( $items as $logid ) {
828 - $event = LogReader::newFromTitle( $title, $logid );
 955+ $event = LogReader::newRowFromTitle( $title, $logid );
829956 if( is_null($event) ) {
830 - return false;
 957+ $success = false;
 958+ continue; // Must exist
831959 } else if( !LogViewer::userCan($event, Revision::DELETED_RESTRICTED) || $event->log_type=='oversight' ) {
832960 // Don't hide from oversight log!!!
833 - $UserAllowedAll=false;
 961+ $userAllowedAll=false;
834962 continue;
835963 }
836964 $logtype = $event->log_type;
@@ -855,12 +983,12 @@
856984 }
857985 }
858986 // Where all revs allowed to be set?
859 - if( !$UserAllowedAll ) {
 987+ if( !$userAllowedAll ) {
860988 $wgOut->permissionRequired( 'hiderevision' );
861989 return false;
862990 }
863991
864 - return true;
 992+ return $success;
865993 }
866994
867995 /**
@@ -920,11 +1048,14 @@
9211049 __METHOD__ );
9221050 }
9231051
924 - // Use of $timeframe for Image objects can create thumbnails of oldimages
9251052 $imgtitle = Title::makeTitle( NS_IMAGE, $oimage->name );
9261053 $image = new Image( $imgtitle );
9271054 $image->purgeCache(); // Clear any thumbnails/purge squid cache
9281055
 1056+ # Invalidate cache for all pages using this file
 1057+ $update = new HTMLCacheUpdate( $imgtitle, 'imagelinks' );
 1058+ $update->doUpdate();
 1059+
9291060 return "{$timestamp}!{$key}";
9301061 }
9311062
@@ -987,7 +1118,16 @@
9881119 array( 'oi_archive_name' => "{$timestamp}!{$oimage->name}" ),
9891120 array( 'oi_name' => $oimage->name, 'oi_archive_name' => $oimage->archive_name ),
9901121 __METHOD__ );
 1122+
 1123+ // Use of $time for Image objects can create thumbnails of oldimages
 1124+ $imgtitle = Title::makeTitle( NS_IMAGE, $oimage->name );
 1125+ $image = new Image( $imgtitle );
 1126+ $image->purgeCache(); // Clear any thumbnails/purge squid cache
9911127
 1128+ # Invalidate cache for all pages using this file
 1129+ $update = new HTMLCacheUpdate( $imgtitle, 'imagelinks' );
 1130+ $update->doUpdate();
 1131+
9921132 return $timestamp;
9931133 }
9941134
@@ -1106,7 +1246,8 @@
11071247 $logtype = ( $bitfield & Revision::DELETED_RESTRICTED ) ? 'oversight' : 'delete';
11081248 // Add params for effected page and ids
11091249 $params = array( $target->getPrefixedText(), $param, implode( ',', $items) );
1110 - $log = new LogPage( $logtype );
 1250+ $log = new LogPage( $logtype );
 1251+ // XXX: hack, do this better
11111252 if( $param=='logid' ) {
11121253 $reason = wfMsgExt('logdelete-logaction', array('parsemag'), $count, $bitfield, $target->getPrefixedText() );
11131254 if($comment) $reason .= ": $comment";
Index: branches/phase3_rev_deleted/includes/AutoLoader.php
@@ -22,6 +22,7 @@
2323 'TurckBagOStuff' => 'includes/BagOStuff.php',
2424 'APCBagOStuff' => 'includes/BagOStuff.php',
2525 'eAccelBagOStuff' => 'includes/BagOStuff.php',
 26+ 'XCacheBagOStuff' => 'includes/BagOStuff.php',
2627 'DBABagOStuff' => 'includes/BagOStuff.php',
2728 'Block' => 'includes/Block.php',
2829 'HTMLFileCache' => 'includes/HTMLFileCache.php',
@@ -190,6 +191,7 @@
191192 'MostimagesPage' => 'includes/SpecialMostimages.php',
192193 'MostlinkedPage' => 'includes/SpecialMostlinked.php',
193194 'MostlinkedCategoriesPage' => 'includes/SpecialMostlinkedcategories.php',
 195+ 'SpecialMostlinkedtemplates' => 'includes/SpecialMostlinkedtemplates.php',
194196 'MostrevisionsPage' => 'includes/SpecialMostrevisions.php',
195197 'FewestrevisionsPage' => 'includes/SpecialFewestrevisions.php',
196198 'MovePageForm' => 'includes/SpecialMovepage.php',
@@ -208,6 +210,7 @@
209211 'ShortPagesPage' => 'includes/SpecialShortpages.php',
210212 'UncategorizedCategoriesPage' => 'includes/SpecialUncategorizedcategories.php',
211213 'UncategorizedPagesPage' => 'includes/SpecialUncategorizedpages.php',
 214+ 'UncategorizedTemplatesPage' => 'includes/SpecialUncategorizedtemplates.php',
212215 'PageArchive' => 'includes/SpecialUndelete.php',
213216 'UndeleteForm' => 'includes/SpecialUndelete.php',
214217 'DBUnlockForm' => 'includes/SpecialUnlockdb.php',
@@ -251,6 +254,7 @@
252255 # filerepo
253256 'ArchivedFile' => 'includes/filerepo/ArchivedFile.php',
254257 'File' => 'includes/filerepo/File.php',
 258+ 'FileRepo' => 'includes/filerepo/FileRepo.php',
255259 'ForeignDBFile' => 'includes/filerepo/ForeignDBFile.php',
256260 'ForeignDBRepo' => 'includes/filerepo/ForeignDBRepo.php',
257261 'FSRepo' => 'includes/filerepo/FSRepo.php',
@@ -302,6 +306,7 @@
303307 'ApiQueryBase' => 'includes/api/ApiQueryBase.php',
304308 'ApiQueryBacklinks' => 'includes/api/ApiQueryBacklinks.php',
305309 'ApiQueryCategories' => 'includes/api/ApiQueryCategories.php',
 310+ 'ApiQueryCategoryMembers' => 'includes/api/ApiQueryCategoryMembers.php',
306311 'ApiQueryContributions' => 'includes/api/ApiQueryUserContributions.php',
307312 'ApiQueryExternalLinks' => 'includes/api/ApiQueryExternalLinks.php',
308313 'ApiQueryImages' => 'includes/api/ApiQueryImages.php',
Index: branches/phase3_rev_deleted/includes/Setup.php
@@ -66,6 +66,7 @@
6767 'hashLevels' => $wgHashedUploadDirectory ? 2 : 0,
6868 'thumbScriptUrl' => $wgThumbnailScriptPath,
6969 'transformVia404' => !$wgGenerateThumbnailOnParse,
 70+ 'initialCapital' => $wgCapitalLinks,
7071 );
7172 }
7273 /**
Index: branches/phase3_rev_deleted/includes/PatrolLog.php
@@ -49,11 +49,16 @@
5050 list( $cur, /* $prev */, $auto ) = $params;
5151 # Standard link to the page in question
5252 $link = $skin->makeLinkObj( $title );
53 - # Generate a diff link
54 - $bits[] = 'oldid=' . urlencode( $cur );
55 - $bits[] = 'diff=prev';
56 - $bits = implode( '&', $bits );
57 - $diff = $skin->makeLinkObj( $title, htmlspecialchars( wfMsg( 'patrol-log-diff', $cur ) ), $bits );
 53+ if( $title->exists() ) {
 54+ # Generate a diff link
 55+ $bits[] = 'oldid=' . urlencode( $cur );
 56+ $bits[] = 'diff=prev';
 57+ $bits = implode( '&', $bits );
 58+ $diff = $skin->makeKnownLinkObj( $title, htmlspecialchars( wfMsg( 'patrol-log-diff', $cur ) ), $bits );
 59+ } else {
 60+ # Don't bother with a diff link, it's useless
 61+ $diff = htmlspecialchars( wfMsg( 'patrol-log-diff', $cur ) );
 62+ }
5863 # Indicate whether or not the patrolling was automatic
5964 $auto = $auto ? wfMsgHtml( 'patrol-log-auto' ) : '';
6065 # Put it all together
Index: branches/phase3_rev_deleted/includes/SpecialPage.php
@@ -94,12 +94,14 @@
9595 'Uncategorizedpages' => array( 'SpecialPage', 'Uncategorizedpages' ),
9696 'Uncategorizedcategories' => array( 'SpecialPage', 'Uncategorizedcategories' ),
9797 'Uncategorizedimages' => array( 'SpecialPage', 'Uncategorizedimages' ),
 98+ 'Uncategorizedtemplates' => array( 'SpecialPage', 'Uncategorizedtemplates' ),
9899 'Unusedcategories' => array( 'SpecialPage', 'Unusedcategories' ),
99100 'Unusedimages' => array( 'SpecialPage', 'Unusedimages' ),
100101 'Wantedpages' => array( 'IncludableSpecialPage', 'Wantedpages' ),
101102 'Wantedcategories' => array( 'SpecialPage', 'Wantedcategories' ),
102103 'Mostlinked' => array( 'SpecialPage', 'Mostlinked' ),
103104 'Mostlinkedcategories' => array( 'SpecialPage', 'Mostlinkedcategories' ),
 105+ 'Mostlinkedtemplates' => array( 'SpecialPage', 'Mostlinkedtemplates' ),
104106 'Mostcategories' => array( 'SpecialPage', 'Mostcategories' ),
105107 'Mostimages' => array( 'SpecialPage', 'Mostimages' ),
106108 'Mostrevisions' => array( 'SpecialPage', 'Mostrevisions' ),
@@ -177,7 +179,7 @@
178180 }
179181
180182 if( $wgEmailAuthentication ) {
181 - self::$mList['Confirmemail'] = array( 'UnlistedSpecialPage', 'Confirmemail' );
 183+ self::$mList['Confirmemail'] = 'EmailConfirmation';
182184 }
183185
184186 # Add extension special pages
@@ -377,6 +379,28 @@
378380 }
379381 return $pages;
380382 }
 383+
 384+ /**
 385+ * Return categorised listable log pages which are available
 386+ * for the current user, but not for everyone
 387+ * @static
 388+ */
 389+ static function getRestrictedLogs() {
 390+ global $wgUser, $wgLogRestrictions, $wgLogNames;
 391+
 392+ $pages = array();
 393+
 394+ if ( isset($wgLogRestrictions) ) {
 395+ foreach ( $wgLogRestrictions as $type => $restriction ) {
 396+ $page = SpecialPage::getTitleFor( 'Log', $type );
 397+ if ( $restriction !='' && $restriction !='*' && $wgUser->isAllowed( $restriction ) ) {
 398+ $name = wfMsgHtml( $wgLogNames[$type] );
 399+ $pages[$name] = $page;
 400+ }
 401+ }
 402+ }
 403+ return $pages;
 404+ }
381405
382406 /**
383407 * Execute a special page path.
Index: branches/phase3_rev_deleted/includes/ParserOutput.php
@@ -103,7 +103,7 @@
104104 array('img_name' => $name),
105105 __METHOD__ );
106106 }
107 - $timestamp = $timestamp ? $timestamp : 0;
 107+ $timestamp = $timestamp ? $timestamp : null;
108108 $this->mImageTimestamps[$name] = $timestamp; // For versioning
109109 }
110110
Index: branches/phase3_rev_deleted/includes/LogPage.php
@@ -72,16 +72,29 @@
7373 $newId = $dbw->insertId();
7474
7575 # And update recentchanges
76 - if ( $this->updateRecentChanges ) {
77 - # Don't add private logs to RC!!!
78 - if ( !isset($wgLogRestrictions[$this->type]) || $wgLogRestrictions[$this->type]=='*' ) {
79 - RecentChange::notifyLog( $now, $this->target, $wgUser, $this->actionText, '',
80 - $this->type, $this->action, $this->target, $this->comment, $this->params, $newId );
 76+ if( $this->updateRecentChanges ) {
 77+ # Don't add private logs to RC!
 78+ if( !isset($wgLogRestrictions[$this->type]) || $wgLogRestrictions[$this->type]=='*' ) {
 79+ $titleObj = SpecialPage::getTitleFor( 'Log', $this->type );
 80+ $rcComment = $this->getRcComment();
 81+ RecentChange::notifyLog( $now, $titleObj, $wgUser, $rcComment, '',
 82+ $this->type, $this->action, $this->target, $this->comment, $this->params );
8183 }
8284 }
8385 return true;
8486 }
8587
 88+ public function getRcComment() {
 89+ $rcComment = $this->actionText;
 90+ if( '' != $this->comment ) {
 91+ if ($rcComment == '')
 92+ $rcComment = $this->comment;
 93+ else
 94+ $rcComment .= ': ' . $this->comment;
 95+ }
 96+ return $rcComment;
 97+ }
 98+
8699 /**
87100 * @static
88101 */
Index: branches/phase3_rev_deleted/includes/User.php
@@ -2149,6 +2149,17 @@
21502150 return $this->mBlock && $this->mBlock->mCreateAccount;
21512151 }
21522152
 2153+ /**
 2154+ * Determine if the user is blocked from using Special:Emailuser.
 2155+ *
 2156+ * @public
 2157+ * @return boolean
 2158+ */
 2159+ function isBlockedFromEmailuser() {
 2160+ $this->getBlockedStatus();
 2161+ return $this->mBlock && $this->mBlock->mBlockEmail;
 2162+ }
 2163+
21532164 function isAllowedToCreateAccount() {
21542165 return $this->isAllowed( 'createaccount' ) && !$this->isBlockedFromCreateAccount();
21552166 }
Index: branches/phase3_rev_deleted/includes/SpecialIpblocklist.php
@@ -265,7 +265,7 @@
266266 if( is_null( $msg ) ) {
267267 $msg = array();
268268 $keys = array( 'infiniteblock', 'expiringblock', 'contribslink', 'unblocklink',
269 - 'anononlyblock', 'createaccountblock', 'noautoblockblock' );
 269+ 'anononlyblock', 'createaccountblock', 'noautoblockblock', 'emailblock' );
270270 foreach( $keys as $key ) {
271271 $msg[$key] = wfMsgHtml( $key );
272272 }
@@ -306,6 +306,10 @@
307307 $properties[] = $msg['noautoblockblock'];
308308 }
309309
 310+ if ( $block->mBlockEmail && $block->mUser ) {
 311+ $properties[] = $msg['emailblock'];
 312+ }
 313+
310314 $properties = implode( ', ', $properties );
311315
312316 $line = wfMsgReplaceArgs( $msg['blocklistline'], array( $formattedTime, $blocker, $target, $properties ) );
Index: branches/phase3_rev_deleted/includes/SpecialLog.php
@@ -50,7 +50,26 @@
5151 $this->db = wfGetDB( DB_SLAVE );
5252 $this->setupQuery( $request );
5353 }
 54+
 55+ /**
 56+ * Returns a row of log data
 57+ * @param Title $title
 58+ * @param integer $logid, optional
 59+ * @private
 60+ */
 61+ function newRowFromTitle( $title, $logid ) {
 62+ $fname = 'LogReader::newFromTitle';
5463
 64+ $dbr = wfGetDB( DB_SLAVE );
 65+ $row = $dbr->selectRow( 'logging', array('*'),
 66+ array('log_id' => intval( $logid ),
 67+ 'log_namespace' => $title->getNamespace(),
 68+ 'log_title' => $title->getDBkey() ),
 69+ $fname );
 70+
 71+ return $row;
 72+ }
 73+
5574 /**
5675 * Basic setup and applies the limiting factors from the WebRequest object.
5776 * @param WebRequest $request
@@ -74,7 +93,8 @@
7594
7695 // XXX This all needs to use Pager, ugly hack for now.
7796 global $wgMiserMode;
78 - if ($wgMiserMode && ($this->offset >10000)) $this->offset=10000;
 97+ if( $wgMiserMode )
 98+ $this->offset = min( $this->offset, 10000 );
7999 }
80100
81101 /**
@@ -236,29 +256,21 @@
237257 }
238258
239259 /**
240 - * Returns a row of log data
241 - * @param Title $title
242 - * @param integer $logid, optional
243 - * @private
244 - */
245 - function newFromTitle( $title, $logid=0 ) {
246 - $fname = 'LogReader::newFromTitle';
 260+ * Is there at least one row?
 261+ *
 262+ * @return bool
 263+ */
 264+ public function hasRows() {
 265+ # Little hack...
 266+ $limit = $this->limit;
 267+ $this->limit = 1;
 268+ $res = $this->db->query( $this->getQuery() );
 269+ $this->limit = $limit;
 270+ $ret = $this->db->numRows( $res ) > 0;
 271+ $this->db->freeResult( $res );
 272+ return $ret;
 273+ }
247274
248 - $dbr = wfGetDB( DB_SLAVE );
249 - $res = $dbr->select( 'logging', array('*'),
250 - array('log_id' => intval( $logid ),
251 - 'log_namespace' => $title->getNamespace(),
252 - 'log_title' => $title->getDBkey() ),
253 - $fname );
254 -
255 - if ( $res ) {
256 - $ret = $dbr->fetchObject( $res );
257 - if ( $ret ) {
258 - return $ret;
259 - }
260 - }
261 - return null;
262 - }
263275 }
264276
265277 /**
@@ -317,33 +329,6 @@
318330 }
319331 }
320332
321 - /**
322 - * Determine if the current user is allowed to view a particular
323 - * field of this event, if it's marked as deleted.
324 - * @param int $field
325 - * @return bool
326 - */
327 - function userCan( $event, $field ) {
328 - if( ( $event->log_deleted & $field ) == $field ) {
329 - global $wgUser;
330 - $permission = ( $event->log_deleted & Revision::DELETED_RESTRICTED ) == Revision::DELETED_RESTRICTED
331 - ? 'hiderevision'
332 - : 'deleterevision';
333 - wfDebug( "Checking for $permission due to $field match on $event->log_deleted\n" );
334 - return $wgUser->isAllowed( $permission );
335 - } else {
336 - return true;
337 - }
338 - }
339 -
340 - /**
341 - * int $field one of DELETED_* bitfield constants
342 - * @return bool
343 - */
344 - function isDeleted( $event, $field ) {
345 - return ($event->log_deleted & $field) == $field;
346 - }
347 -
348333 /**
349334 * Fetch event's user id if it's available to all users
350335 * @return int
@@ -478,13 +463,25 @@
479464 }
480465
481466 function doShowList( &$out, $result ) {
 467+ global $wgLang;
 468+
 469+ $lastdate = '';
 470+ $listopen = false;
482471 // Rewind result pointer and go through it again, making the HTML
483 - $html = "\n<ul>\n";
 472+ $html = '';
484473 $result->seek( 0 );
485474 while( $s = $result->fetchObject() ) {
486 - $html .= $this->logLine( $s );
 475+ $date = $wgLang->date( $s->log_timestamp, /* adj */ true );
 476+ if ( $date != $lastdate ) {
 477+ if ( $listopen ) { $html .= Xml::closeElement( 'ul' ); }
 478+ $html .= Xml::element('h4', null, $date) . "\n";
 479+ $html .= Xml::openElement( 'ul' );
 480+ $listopen = true;
 481+ $lastdate = $date;
 482+ }
 483+ $html .= Xml::tags('li', null, $this->logLine( $s ) ) . "\n";
487484 }
488 - $html .= "\n</ul>\n";
 485+ if ( $listopen ) { $html .= Xml::closeElement( 'ul' ); }
489486 $out->addHTML( $html );
490487 $result->free();
491488 }
@@ -503,7 +500,7 @@
504501
505502 $skin = $wgUser->getSkin();
506503 $title = Title::makeTitle( $s->log_namespace, $s->log_title );
507 - $time = $wgLang->timeanddate( wfTimestamp(TS_MW, $s->log_timestamp), true );
 504+ $time = $wgLang->time( wfTimestamp(TS_MW, $s->log_timestamp), true );
508505
509506 // Enter the existence or non-existence of this page into the link cache,
510507 // for faster makeLinkObj() in LogPage::actionText()
@@ -535,7 +532,7 @@
536533 else
537534 $action = $this->logActionText( $s->log_type, $s->log_action, $title, $this->skin, $paramArray );
538535
539 - $out = "<li><tt>$del</tt> $time $userLink $action $comment $revert</li>\n";
 536+ $out = "<tt>$del</tt> $time $userLink $action $comment $revert";
540537 return $out;
541538 }
542539
@@ -580,7 +577,7 @@
581578 if( $s->log_type == 'move' && isset( $paramArray[0] ) ) {
582579 $destTitle = Title::newFromText( $paramArray[0] );
583580 if ( $destTitle ) {
584 - $revert = '(' . $this->skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Movepage' ),
 581+ $reviewlink = '(' . $this->skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Movepage' ),
585582 wfMsg( 'revertmove' ),
586583 'wpOldTitle=' . urlencode( $destTitle->getPrefixedDBkey() ) .
587584 '&wpNewTitle=' . urlencode( $title->getPrefixedDBkey() ) .
@@ -598,13 +595,14 @@
599596 wfMsg( 'unblocklink' ),
600597 'action=unblock&ip=' . urlencode( $s->log_title ) );
601598 // show change protection link
602 - } elseif( $s->log_action == 'protect' && $wgUser->isAllowed( 'protect' ) ) {
 599+ } elseif( ($s->log_action == 'protect' || $s->log_action == 'modify') && $wgUser->isAllowed( 'protect' ) ) {
 600+ $title = Title::makeTitle( $s->log_namespace, $s->log_title );
603601 $reviewlink = $this->skin->makeKnownLink( $title->getPrefixedDBkey() ,
604602 wfMsg( 'protect_change' ),
605603 'action=unprotect' );
606604 // show user tool links for self created users
607605 } elseif( $s->log_action == 'create2' ) {
608 - $revert = $this->skin->userToolLinksRedContribs( $s->log_user, $s->log_title );
 606+ $reviewlink = $this->skin->userToolLinksRedContribs( $s->log_user, $s->log_title );
609607 // do not show $comment for self created accounts. It includes wrong user tool links:
610608 // 'blockip' for users w/o block allowance and broken links for very long usernames (bug 4756)
611609 $comment = '';
@@ -644,11 +642,11 @@
645643 $Ids = explode( ',', $paramArray[2] );
646644 foreach ( $Ids as $n => $id ) {
647645 $reviewlink .= ' '.$this->skin->makeKnownLinkObj( $revdel, '#'.($n+1),
648 - wfArrayToCGI( array('target' => $paramArray[0], $paramArray[1] => $id ) ) );
 646+ wfArrayToCGI( array('target' => $paramArray[0], $paramArray[1] => $id ) ) );
649647 }
650648 }
651649 }
652 - $reviewlink = ( $reviewlink=='' ) ? "" : "&nbsp;&nbsp;&nbsp;($reviewlink) ";
 650+ $reviewlink = ($reviewlink=='') ? "" : "&nbsp;&nbsp;&nbsp;($reviewlink) ";
653651 return $reviewlink;
654652 }
655653
@@ -772,6 +770,33 @@
773771 $this->numResults < $limit);
774772 $out->addHTML( '<p>' . $html . '</p>' );
775773 }
 774+
 775+ /**
 776+ * Determine if the current user is allowed to view a particular
 777+ * field of this event, if it's marked as deleted.
 778+ * @param int $field
 779+ * @return bool
 780+ */
 781+ public static function userCan( $event, $field ) {
 782+ if( ( $event->log_deleted & $field ) == $field ) {
 783+ global $wgUser;
 784+ $permission = ( $event->log_deleted & Revision::DELETED_RESTRICTED ) == Revision::DELETED_RESTRICTED
 785+ ? 'hiderevision'
 786+ : 'deleterevision';
 787+ wfDebug( "Checking for $permission due to $field match on $event->log_deleted\n" );
 788+ return $wgUser->isAllowed( $permission );
 789+ } else {
 790+ return true;
 791+ }
 792+ }
 793+
 794+ /**
 795+ * int $field one of DELETED_* bitfield constants
 796+ * @return bool
 797+ */
 798+ public static function isDeleted( $event, $field ) {
 799+ return ($event->log_deleted & $field) == $field;
 800+ }
776801 }
777802
778803 /**
Index: branches/phase3_rev_deleted/includes/SpecialUpload.php
@@ -22,18 +22,19 @@
2323 /**#@+
2424 * @access private
2525 */
26 - var $mUploadFile, $mUploadDescription, $mLicense ,$mIgnoreWarning, $mUploadError;
27 - var $mUploadSaveName, $mUploadTempName, $mUploadSize, $mUploadOldVersion;
28 - var $mUploadCopyStatus, $mUploadSource, $mReUpload, $mAction, $mUpload;
29 - var $mOname, $mSessionKey, $mStashed, $mDestFile, $mRemoveTempFile, $mSourceType;
30 - var $mUploadTempFileSize = 0;
31 - var $mImage;
 26+ var $mComment, $mLicense, $mIgnoreWarning, $mCurlError;
 27+ var $mDestName, $mTempPath, $mFileSize, $mFileProps;
 28+ var $mCopyrightStatus, $mCopyrightSource, $mReUpload, $mAction, $mUploadClicked;
 29+ var $mSrcName, $mSessionKey, $mStashed, $mDesiredDestName, $mRemoveTempFile, $mSourceType;
 30+ var $mCurlDestHandle;
 31+ var $mLocalFile;
3232
3333 # Placeholders for text injection by hooks (must be HTML)
3434 # extensions should take care to _append_ to the present value
3535 var $uploadFormTextTop;
3636 var $uploadFormTextAfterSummary;
3737
 38+ const SESSION_VERSION = 1;
3839 /**#@-*/
3940
4041 /**
@@ -43,7 +44,7 @@
4445 */
4546 function UploadForm( &$request ) {
4647 global $wgAllowCopyUploads;
47 - $this->mDestFile = $request->getText( 'wpDestFile' );
 48+ $this->mDesiredDestName = $request->getText( 'wpDestFile' );
4849
4950 if( !$request->wasPosted() ) {
5051 # GET requests just give the main form; no data except wpDestfile.
@@ -56,21 +57,22 @@
5758
5859 $this->mIgnoreWarning = $request->getCheck( 'wpIgnoreWarning' );
5960 $this->mReUpload = $request->getCheck( 'wpReUpload' );
60 - $this->mUpload = $request->getCheck( 'wpUpload' );
 61+ $this->mUploadClicked = $request->getCheck( 'wpUpload' );
6162
62 - $this->mUploadDescription = $request->getText( 'wpUploadDescription' );
 63+ $this->mComment = $request->getText( 'wpUploadDescription' );
6364 $this->mLicense = $request->getText( 'wpLicense' );
64 - $this->mUploadCopyStatus = $request->getText( 'wpUploadCopyStatus' );
65 - $this->mUploadSource = $request->getText( 'wpUploadSource' );
 65+ $this->mCopyrightStatus = $request->getText( 'wpUploadCopyStatus' );
 66+ $this->mCopyrightSource = $request->getText( 'wpUploadSource' );
6667 $this->mWatchthis = $request->getBool( 'wpWatchthis' );
67 - $this->mSourceType = $request->getText( 'wpSourceType' );
 68+ $this->mSourceType = $request->getText( 'wpSourceType' );
6869 wfDebug( "UploadForm: watchthis is: '$this->mWatchthis'\n" );
6970
7071 $this->mAction = $request->getVal( 'action' );
7172
7273 $this->mSessionKey = $request->getInt( 'wpSessionKey' );
7374 if( !empty( $this->mSessionKey ) &&
74 - isset( $_SESSION['wsUploadData'][$this->mSessionKey] ) ) {
 75+ isset( $_SESSION['wsUploadData'][$this->mSessionKey]['version'] ) &&
 76+ $_SESSION['wsUploadData'][$this->mSessionKey]['version'] == self::SESSION_VERSION ) {
7577 /**
7678 * Confirming a temporarily stashed upload.
7779 * We don't want path names to be forged, so we keep
@@ -78,10 +80,11 @@
7981 * an opaque key to the user agent.
8082 */
8183 $data = $_SESSION['wsUploadData'][$this->mSessionKey];
82 - $this->mUploadTempName = $data['mUploadTempName'];
83 - $this->mUploadSize = $data['mUploadSize'];
84 - $this->mOname = $data['mOname'];
85 - $this->mUploadError = 0/*UPLOAD_ERR_OK*/;
 84+ $this->mTempPath = $data['mTempPath'];
 85+ $this->mFileSize = $data['mFileSize'];
 86+ $this->mSrcName = $data['mSrcName'];
 87+ $this->mFileProps = $data['mFileProps'];
 88+ $this->mCurlError = 0/*UPLOAD_ERR_OK*/;
8689 $this->mStashed = true;
8790 $this->mRemoveTempFile = false;
8891 } else {
@@ -101,10 +104,11 @@
102105 * @access private
103106 */
104107 function initializeFromUpload( $request ) {
105 - $this->mUploadTempName = $request->getFileTempName( 'wpUploadFile' );
106 - $this->mUploadSize = $request->getFileSize( 'wpUploadFile' );
107 - $this->mOname = $request->getFileName( 'wpUploadFile' );
108 - $this->mUploadError = $request->getUploadError( 'wpUploadFile' );
 108+ $this->mTempPath = $request->getFileTempName( 'wpUploadFile' );
 109+ $this->mFileSize = $request->getFileSize( 'wpUploadFile' );
 110+ $this->mSrcName = $request->getFileName( 'wpUploadFile' );
 111+ $this->mCurlError = $request->getUploadError( 'wpUploadFile' );
 112+ $this->mFileProps = File::getPropsFromPath( $this->mTempPath );
109113 $this->mSessionKey = false;
110114 $this->mStashed = false;
111115 $this->mRemoveTempFile = false; // PHP will handle this
@@ -119,10 +123,10 @@
120124 $url = $request->getText( 'wpUploadFileURL' );
121125 $local_file = tempnam( $wgTmpDirectory, 'WEBUPLOAD' );
122126
123 - $this->mUploadTempName = $local_file;
124 - $this->mUploadError = $this->curlCopy( $url, $local_file );
125 - $this->mUploadSize = $this->mUploadTempFileSize;
126 - $this->mOname = array_pop( explode( '/', $url ) );
 127+ $this->mTempPath = $local_file;
 128+ $this->mFileSize = 0; # Will be set by curlCopy
 129+ $this->mCurlError = $this->curlCopy( $url, $local_file );
 130+ $this->mSrcName = array_pop( explode( '/', $url ) );
127131 $this->mSessionKey = false;
128132 $this->mStashed = false;
129133
@@ -151,8 +155,8 @@
152156 }
153157
154158 # Open temporary file
155 - $this->mUploadTempFile = @fopen( $this->mUploadTempName, "wb" );
156 - if( $this->mUploadTempFile === false ) {
 159+ $this->mCurlDestHandle = @fopen( $this->mTempPath, "wb" );
 160+ if( $this->mCurlDestHandle === false ) {
157161 # Could not open temporary file to write in
158162 $wgOut->errorPage( 'upload-file-error', 'upload-file-error-text');
159163 return true;
@@ -170,8 +174,8 @@
171175 // if ( $error ) print curl_error ( $ch ) ; # Debugging output
172176 curl_close( $ch );
173177
174 - fclose( $this->mUploadTempFile );
175 - unset( $this->mUploadTempFile );
 178+ fclose( $this->mCurlDestHandle );
 179+ unset( $this->mCurlDestHandle );
176180 if( $error ) {
177181 unlink( $dest );
178182 if( wfEmptyMsg( "upload-curl-error$errornum", wfMsg("upload-curl-error$errornum") ) )
@@ -192,11 +196,11 @@
193197 function uploadCurlCallback( $ch, $data ) {
194198 global $wgMaxUploadSize;
195199 $length = strlen( $data );
196 - $this->mUploadTempFileSize += $length;
197 - if( $this->mUploadTempFileSize > $wgMaxUploadSize ) {
 200+ $this->mFileSize += $length;
 201+ if( $this->mFileSize > $wgMaxUploadSize ) {
198202 return 0;
199203 }
200 - fwrite( $this->mUploadTempFile, $data );
 204+ fwrite( $this->mCurlDestHandle, $data );
201205 return $length;
202206 }
203207
@@ -206,11 +210,11 @@
207211 */
208212 function execute() {
209213 global $wgUser, $wgOut;
210 - global $wgEnableUploads, $wgUploadDirectory;
 214+ global $wgEnableUploads;
211215
212216 # Check uploading enabled
213217 if( !$wgEnableUploads ) {
214 - $wgOut->showErrorPage( 'uploaddisabled', 'uploaddisabledtext', array( $this->mDestFile ) );
 218+ $wgOut->showErrorPage( 'uploaddisabled', 'uploaddisabledtext', array( $this->mDesiredDestName ) );
215219 return;
216220 }
217221
@@ -235,18 +239,12 @@
236240 return;
237241 }
238242
239 - /** Check if the image directory is writeable, this is a common mistake */
240 - if( !is_writeable( $wgUploadDirectory ) ) {
241 - $wgOut->addWikiText( wfMsg( 'upload_directory_read_only', $wgUploadDirectory ) );
242 - return;
243 - }
244 -
245243 if( $this->mReUpload ) {
246244 if( !$this->unsaveUploadedFile() ) {
247245 return;
248246 }
249247 $this->mainUploadForm();
250 - } else if( 'submit' == $this->mAction || $this->mUpload ) {
 248+ } else if( 'submit' == $this->mAction || $this->mUploadClicked ) {
251249 $this->processUpload();
252250 } else {
253251 $this->mainUploadForm();
@@ -272,7 +270,7 @@
273271 }
274272
275273 /* Check for PHP error if any, requires php 4.2 or newer */
276 - if( $this->mUploadError == 1/*UPLOAD_ERR_INI_SIZE*/ ) {
 274+ if( $this->mCurlError == 1/*UPLOAD_ERR_INI_SIZE*/ ) {
277275 $this->mainUploadForm( wfMsgHtml( 'largefileserver' ) );
278276 return;
279277 }
@@ -280,16 +278,16 @@
281279 /**
282280 * If there was no filename or a zero size given, give up quick.
283281 */
284 - if( trim( $this->mOname ) == '' || empty( $this->mUploadSize ) ) {
 282+ if( trim( $this->mSrcName ) == '' || empty( $this->mFileSize ) ) {
285283 $this->mainUploadForm( wfMsgHtml( 'emptyfile' ) );
286284 return;
287285 }
288286
289287 # Chop off any directories in the given filename
290 - if( $this->mDestFile ) {
291 - $basename = wfBaseName( $this->mDestFile );
 288+ if( $this->mDesiredDestName ) {
 289+ $basename = wfBaseName( $this->mDesiredDestName );
292290 } else {
293 - $basename = wfBaseName( $this->mOname );
 291+ $basename = wfBaseName( $this->mSrcName );
294292 }
295293
296294 /**
@@ -321,26 +319,26 @@
322320 * out of it. We'll strip some silently that Title would die on.
323321 */
324322 $filtered = preg_replace ( "/[^".Title::legalChars()."]|:/", '-', $basename );
325 - $nt = Title::newFromText( $filtered );
 323+ $nt = Title::makeTitleSafe( NS_IMAGE, $filtered );
326324 if( is_null( $nt ) ) {
327325 $this->uploadError( wfMsgWikiHtml( 'illegalfilename', htmlspecialchars( $filtered ) ) );
328326 return;
329327 }
330 - $nt =& Title::makeTitle( NS_IMAGE, $nt->getDBkey() );
331 - $this->mUploadSaveName = $nt->getDBkey();
 328+ $this->mLocalFile = wfLocalFile( $nt );
 329+ $this->mDestName = $this->mLocalFile->getName();
332330
333331 /**
334332 * If the image is protected, non-sysop users won't be able
335333 * to modify it by uploading a new revision.
336334 */
337 - if( !$nt->userCan( 'edit' ) ) {
 335+ if( !$nt->userCan( 'edit' ) || !$nt->userCan( 'upload' ) ) {
338336 return $this->uploadError( wfMsgWikiHtml( 'protectedpage' ) );
339337 }
340338
341339 /**
342340 * In some cases we may forbid overwriting of existing files.
343341 */
344 - $overwrite = $this->checkOverwrite( $this->mUploadSaveName );
 342+ $overwrite = $this->checkOverwrite( $this->mDestName );
345343 if( WikiError::isError( $overwrite ) ) {
346344 return $this->uploadError( $overwrite->toString() );
347345 }
@@ -351,9 +349,9 @@
352350 if ($finalExt == '') {
353351 return $this->uploadError( wfMsgExt( 'filetype-missing', array ( 'parseinline' ) ) );
354352 } elseif ( $this->checkFileExtensionList( $ext, $wgFileBlacklist ) ||
355 - ($wgStrictFileExtensions &&
356 - !$this->checkFileExtension( $finalExt, $wgFileExtensions ) ) ) {
357 - return $this->uploadError( wfMsgExt( 'filetype-badtype', array ( 'parseinline' ), htmlspecialchars( $finalExt ), implode ( ', ', $wgFileExtensions ) ) );
 353+ ($wgStrictFileExtensions && !$this->checkFileExtension( $finalExt, $wgFileExtensions ) ) ) {
 354+ return $this->uploadError( wfMsgExt( 'filetype-badtype', array ( 'parseinline' ),
 355+ htmlspecialchars( $finalExt ), implode ( ', ', $wgFileExtensions ) ) );
358356 }
359357
360358 /**
@@ -363,22 +361,23 @@
364362 */
365363 if( !$this->mStashed ) {
366364 $this->checkMacBinary();
367 - $veri = $this->verify( $this->mUploadTempName, $finalExt );
 365+ $veri = $this->verify( $this->mTempPath, $finalExt );
368366
369367 if( $veri !== true ) { //it's a wiki error...
370368 return $this->uploadError( $veri->toString() );
371369 }
372 - }
373370
374 - /**
375 - * Provide an opportunity for extensions to add futher checks
376 - */
377 - $error = '';
378 - if( !wfRunHooks( 'UploadVerification',
379 - array( $this->mUploadSaveName, $this->mUploadTempName, &$error ) ) ) {
380 - return $this->uploadError( $error );
 371+ /**
 372+ * Provide an opportunity for extensions to add futher checks
 373+ */
 374+ $error = '';
 375+ if( !wfRunHooks( 'UploadVerification',
 376+ array( $this->mDestName, $this->mTempPath, &$error ) ) ) {
 377+ return $this->uploadError( $error );
 378+ }
381379 }
382380
 381+
383382 /**
384383 * Check for non-fatal conditions
385384 */
@@ -389,31 +388,31 @@
390389 if( $wgCapitalLinks ) {
391390 $filtered = ucfirst( $filtered );
392391 }
393 - if( $this->mUploadSaveName != $filtered ) {
394 - $warning .= '<li>'.wfMsgHtml( 'badfilename', htmlspecialchars( $this->mUploadSaveName ) ).'</li>';
 392+ if( $this->mDestName != $filtered ) {
 393+ $warning .= '<li>'.wfMsgHtml( 'badfilename', htmlspecialchars( $this->mDestName ) ).'</li>';
395394 }
396395
397396 global $wgCheckFileExtensions;
398397 if ( $wgCheckFileExtensions ) {
399398 if ( ! $this->checkFileExtension( $finalExt, $wgFileExtensions ) ) {
400 - $warning .= '<li>'.wfMsgExt( 'filetype-badtype', array ( 'parseinline' ), htmlspecialchars( $finalExt ), implode ( ', ', $wgFileExtensions ) ).'</li>';
 399+ $warning .= '<li>'.wfMsgExt( 'filetype-badtype', array ( 'parseinline' ),
 400+ htmlspecialchars( $finalExt ), implode ( ', ', $wgFileExtensions ) ).'</li>';
401401 }
402402 }
403403
404404 global $wgUploadSizeWarning;
405 - if ( $wgUploadSizeWarning && ( $this->mUploadSize > $wgUploadSizeWarning ) ) {
 405+ if ( $wgUploadSizeWarning && ( $this->mFileSize > $wgUploadSizeWarning ) ) {
406406 $skin = $wgUser->getSkin();
407407 $wsize = $skin->formatSize( $wgUploadSizeWarning );
408 - $asize = $skin->formatSize( $this->mUploadSize );
 408+ $asize = $skin->formatSize( $this->mFileSize );
409409 $warning .= '<li>' . wfMsgHtml( 'large-file', $wsize, $asize ) . '</li>';
410410 }
411 - if ( $this->mUploadSize == 0 ) {
 411+ if ( $this->mFileSize == 0 ) {
412412 $warning .= '<li>'.wfMsgHtml( 'emptyfile' ).'</li>';
413413 }
414414
415415 global $wgUser;
416416 $sk = $wgUser->getSkin();
417 - $image = wfLocalFile( $nt );
418417
419418 // Check for uppercase extension. We allow these filenames but check if an image
420419 // with lowercase extension exists already
@@ -422,13 +421,15 @@
423422 $image_lc = wfLocalFile( $nt_lc );
424423 }
425424
426 - if( $image->exists() ) {
 425+ if( $this->mLocalFile->exists() ) {
427426 $dlink = $sk->makeKnownLinkObj( $nt );
428 - if ( $image->allowInlineDisplay() ) {
429 - $dlink2 = $sk->makeImageLinkObj( $nt, wfMsgExt( 'fileexists-thumb', 'parseinline', $dlink ), $nt->getText(), 'right', array(), false, true );
430 - } elseif ( !$image->allowInlineDisplay() && $image->isSafeFile() ) {
431 - $icon = $image->iconThumb();
432 - $dlink2 = '<div style="float:right" id="mw-media-icon"><a href="' . $image->getURL() . '">' . $icon->toHtml() . '</a><br />' . $dlink . '</div>';
 427+ if ( $this->mLocalFile->allowInlineDisplay() ) {
 428+ $dlink2 = $sk->makeImageLinkObj( $nt, wfMsgExt( 'fileexists-thumb', 'parseinline', $dlink ),
 429+ $nt->getText(), 'right', array(), false, true );
 430+ } elseif ( !$this->mLocalFile->allowInlineDisplay() && $this->mLocalFile->isSafeFile() ) {
 431+ $icon = $this->mLocalFile->iconThumb();
 432+ $dlink2 = '<div style="float:right" id="mw-media-icon"><a href="' . $this->mLocalFile->getURL() . '">' .
 433+ $icon->toHtml() . '</a><br />' . $dlink . '</div>';
433434 } else {
434435 $dlink2 = '';
435436 }
@@ -440,17 +441,22 @@
441442 # It's not forbidden but in 99% it makes no sense to upload the same filename with uppercase extension
442443 $dlink = $sk->makeKnownLinkObj( $nt_lc );
443444 if ( $image_lc->allowInlineDisplay() ) {
444 - $dlink2 = $sk->makeImageLinkObj( $nt_lc, wfMsgExt( 'fileexists-thumb', 'parseinline', $dlink ), $nt_lc->getText(), 'right', array(), false, true );
 445+ $dlink2 = $sk->makeImageLinkObj( $nt_lc, wfMsgExt( 'fileexists-thumb', 'parseinline', $dlink ),
 446+ $nt_lc->getText(), 'right', array(), false, true );
445447 } elseif ( !$image_lc->allowInlineDisplay() && $image_lc->isSafeFile() ) {
446448 $icon = $image_lc->iconThumb();
447 - $dlink2 = '<div style="float:right" id="mw-media-icon"><a href="' . $image_lc->getURL() . '">' . $icon->toHtml() . '</a><br />' . $dlink . '</div>';
 449+ $dlink2 = '<div style="float:right" id="mw-media-icon"><a href="' . $image_lc->getURL() . '">' .
 450+ $icon->toHtml() . '</a><br />' . $dlink . '</div>';
448451 } else {
449452 $dlink2 = '';
450453 }
451454
452 - $warning .= '<li>' . wfMsgExt( 'fileexists-extension', 'parsemag' , $partname . '.' . $finalExt , $dlink ) . '</li>' . $dlink2;
 455+ $warning .= '<li>' . wfMsgExt( 'fileexists-extension', 'parsemag' , $partname . '.'
 456+ . $finalExt , $dlink ) . '</li>' . $dlink2;
453457
454 - } elseif ( ( substr( $partname , 3, 3 ) == 'px-' || substr( $partname , 2, 3 ) == 'px-' ) && ereg( "[0-9]{2}" , substr( $partname , 0, 2) ) ) {
 458+ } elseif ( ( substr( $partname , 3, 3 ) == 'px-' || substr( $partname , 2, 3 ) == 'px-' )
 459+ && ereg( "[0-9]{2}" , substr( $partname , 0, 2) ) )
 460+ {
455461 # Check for filenames like 50px- or 180px-, these are mostly thumbnails
456462 $nt_thb = Title::newFromText( substr( $partname , strpos( $partname , '-' ) +1 ) . '.' . $finalExt );
457463 $image_thb = wfLocalFile( $nt_thb );
@@ -458,26 +464,34 @@
459465 # Check if an image without leading '180px-' (or similiar) exists
460466 $dlink = $sk->makeKnownLinkObj( $nt_thb);
461467 if ( $image_thb->allowInlineDisplay() ) {
462 - $dlink2 = $sk->makeImageLinkObj( $nt_thb, wfMsgExt( 'fileexists-thumb', 'parseinline', $dlink ), $nt_thb->getText(), 'right', array(), false, true );
 468+ $dlink2 = $sk->makeImageLinkObj( $nt_thb,
 469+ wfMsgExt( 'fileexists-thumb', 'parseinline', $dlink ),
 470+ $nt_thb->getText(), 'right', array(), false, true );
463471 } elseif ( !$image_thb->allowInlineDisplay() && $image_thb->isSafeFile() ) {
464472 $icon = $image_thb->iconThumb();
465 - $dlink2 = '<div style="float:right" id="mw-media-icon"><a href="' . $image_thb->getURL() . '">' . $icon->toHtml() . '</a><br />' . $dlink . '</div>';
 473+ $dlink2 = '<div style="float:right" id="mw-media-icon"><a href="' .
 474+ $image_thb->getURL() . '">' . $icon->toHtml() . '</a><br />' .
 475+ $dlink . '</div>';
466476 } else {
467477 $dlink2 = '';
468478 }
469479
470 - $warning .= '<li>' . wfMsgExt( 'fileexists-thumbnail-yes', 'parsemag', $dlink ) . '</li>' . $dlink2;
 480+ $warning .= '<li>' . wfMsgExt( 'fileexists-thumbnail-yes', 'parsemag', $dlink ) .
 481+ '</li>' . $dlink2;
471482 } else {
472483 # Image w/o '180px-' does not exists, but we do not like these filenames
473 - $warning .= '<li>' . wfMsgExt( 'file-thumbnail-no', 'parseinline' , substr( $partname , 0, strpos( $partname , '-' ) +1 ) ) . '</li>';
 484+ $warning .= '<li>' . wfMsgExt( 'file-thumbnail-no', 'parseinline' ,
 485+ substr( $partname , 0, strpos( $partname , '-' ) +1 ) ) . '</li>';
474486 }
475487 }
476 - if ( $image->wasDeleted() ) {
 488+ if ( $this->mLocalFile->wasDeleted() ) {
477489 # If the file existed before and was deleted, warn the user of this
478490 # Don't bother doing so if the image exists now, however
479491 $ltitle = SpecialPage::getTitleFor( 'Log' );
480 - $llink = $sk->makeKnownLinkObj( $ltitle, wfMsgHtml( 'deletionlog' ), 'type=delete&page=' . $nt->getPrefixedUrl() );
481 - $warning .= wfOpenElement( 'li' ) . wfMsgWikiHtml( 'filewasdeleted', $llink ) . wfCloseElement( 'li' );
 492+ $llink = $sk->makeKnownLinkObj( $ltitle, wfMsgHtml( 'deletionlog' ),
 493+ 'type=delete&page=' . $nt->getPrefixedUrl() );
 494+ $warning .= wfOpenElement( 'li' ) . wfMsgWikiHtml( 'filewasdeleted', $llink ) .
 495+ wfCloseElement( 'li' );
482496 }
483497
484498 if( $warning != '' ) {
@@ -493,59 +507,24 @@
494508 * Try actually saving the thing...
495509 * It will show an error form on failure.
496510 */
497 - $hasBeenMunged = !empty( $this->mSessionKey ) || $this->mRemoveTempFile;
498 - if( $this->saveUploadedFile( $this->mUploadSaveName,
499 - $this->mUploadTempName,
500 - $hasBeenMunged ) ) {
501 - /**
502 - * Update the upload log and create the description page
503 - * if it's a new file.
504 - */
505 - $this->mImage = wfLocalFile( $this->mUploadSaveName );
506 - $success = $this->mImage->recordUpload( $this->mUploadOldVersion,
507 - $this->mUploadDescription,
508 - $this->mLicense,
509 - $this->mUploadCopyStatus,
510 - $this->mUploadSource,
511 - $this->mWatchthis );
 511+ $pageText = self::getInitialPageText( $this->mComment, $this->mLicense,
 512+ $this->mCopyrightStatus, $this->mCopyrightSource );
512513
513 - if ( $success ) {
514 - $this->showSuccess();
515 - wfRunHooks( 'UploadComplete', array( &$img ) );
516 - } else {
517 - // File::recordUpload() fails if the image went missing, which is
518 - // unlikely, hence the lack of a specialised message
519 - $wgOut->showFileNotFoundError( $this->mUploadSaveName );
 514+ $error = $this->mLocalFile->upload( $this->mTempPath, $this->mComment, $pageText,
 515+ File::DELETE_SOURCE, $this->mFileProps );
 516+ if ( WikiError::isError( $error ) ) {
 517+ $this->showError( $error );
 518+ } else {
 519+ if ( $this->mWatchthis ) {
 520+ global $wgUser;
 521+ $wgUser->addWatch( $this->mLocalFile->getTitle() );
520522 }
 523+ $this->showSuccess();
 524+ wfRunHooks( 'UploadComplete', array( &$img ) );
521525 }
522526 }
523527
524528 /**
525 - * Move the uploaded file from its temporary location to the final
526 - * destination. If a previous version of the file exists, move
527 - * it into the archive subdirectory.
528 - *
529 - * @todo If the later save fails, we may have disappeared the original file.
530 - *
531 - * @param string $saveName
532 - * @param string $tempName full path to the temporary file
533 - * @param bool $useRename if true, doesn't check that the source file
534 - * is a PHP-managed upload temporary
535 - */
536 - function saveUploadedFile( $saveName, $tempName, $useRename = false ) {
537 - global $wgOut, $wgAllowCopyUploads;
538 -
539 - $image = wfLocalFile( $saveName );
540 - $archiveName = $image->publish( $tempName, File::DELETE_SOURCE );
541 - if ( WikiError::isError( $archiveName ) ) {
542 - $this->showError( $archiveName );
543 - return false;
544 - }
545 - $this->mUploadOldVersion = $archiveName;
546 - return true;
547 - }
548 -
549 - /**
550529 * Stash a file in a temporary directory for later processing
551530 * after the user has confirmed it.
552531 *
@@ -579,8 +558,7 @@
580559 * @access private
581560 */
582561 function stashSession() {
583 - $stash = $this->saveTempUploadedFile(
584 - $this->mUploadSaveName, $this->mUploadTempName );
 562+ $stash = $this->saveTempUploadedFile( $this->mDestName, $this->mTempPath );
585563
586564 if( !$stash ) {
587565 # Couldn't save the file.
@@ -589,9 +567,12 @@
590568
591569 $key = mt_rand( 0, 0x7fffffff );
592570 $_SESSION['wsUploadData'][$key] = array(
593 - 'mUploadTempName' => $stash,
594 - 'mUploadSize' => $this->mUploadSize,
595 - 'mOname' => $this->mOname );
 571+ 'mTempPath' => $stash,
 572+ 'mFileSize' => $this->mFileSize,
 573+ 'mSrcName' => $this->mSrcName,
 574+ 'mFileProps' => $this->mFileProps,
 575+ 'version' => self::SESSION_VERSION,
 576+ );
596577 return $key;
597578 }
598579
@@ -602,11 +583,10 @@
603584 */
604585 function unsaveUploadedFile() {
605586 global $wgOut;
606 - wfSuppressWarnings();
607 - $success = unlink( $this->mUploadTempName );
608 - wfRestoreWarnings();
 587+ $repo = RepoGroup::singleton()->getLocalRepo();
 588+ $success = $repo->freeTemp( $this->mTempPath );
609589 if ( ! $success ) {
610 - $wgOut->showFileDeleteError( $this->mUploadTempName );
 590+ $wgOut->showFileDeleteError( $this->mTempPath );
611591 return false;
612592 } else {
613593 return true;
@@ -623,8 +603,8 @@
624604 global $wgUser, $wgOut, $wgContLang;
625605
626606 $sk = $wgUser->getSkin();
627 - $ilink = $sk->makeMediaLinkObj( $this->mImage->getTitle() );
628 - $dname = $wgContLang->getNsText( NS_IMAGE ) . ':'.$this->mUploadSaveName;
 607+ $ilink = $sk->makeMediaLinkObj( $this->mLocalFile->getTitle() );
 608+ $dname = $wgContLang->getNsText( NS_IMAGE ) . ':'.$this->mDestName;
629609 $dlink = $sk->makeKnownLink( $dname, $dname );
630610
631611 $wgOut->addHTML( '<h2>' . wfMsgHtml( 'successfulupload' ) . "</h2>\n" );
@@ -674,8 +654,8 @@
675655 if ( $wgUseCopyrightUpload )
676656 {
677657 $copyright = "
678 - <input type='hidden' name='wpUploadCopyStatus' value=\"" . htmlspecialchars( $this->mUploadCopyStatus ) . "\" />
679 - <input type='hidden' name='wpUploadSource' value=\"" . htmlspecialchars( $this->mUploadSource ) . "\" />
 658+ <input type='hidden' name='wpUploadCopyStatus' value=\"" . htmlspecialchars( $this->mCopyrightStatus ) . "\" />
 659+ <input type='hidden' name='wpUploadSource' value=\"" . htmlspecialchars( $this->mCopyrightSource ) . "\" />
680660 ";
681661 } else {
682662 $copyright = "";
@@ -685,9 +665,9 @@
686666 <form id='uploadwarning' method='post' enctype='multipart/form-data' action='$action'>
687667 <input type='hidden' name='wpIgnoreWarning' value='1' />
688668 <input type='hidden' name='wpSessionKey' value=\"" . htmlspecialchars( $this->mSessionKey ) . "\" />
689 - <input type='hidden' name='wpUploadDescription' value=\"" . htmlspecialchars( $this->mUploadDescription ) . "\" />
 669+ <input type='hidden' name='wpUploadDescription' value=\"" . htmlspecialchars( $this->mComment ) . "\" />
690670 <input type='hidden' name='wpLicense' value=\"" . htmlspecialchars( $this->mLicense ) . "\" />
691 - <input type='hidden' name='wpDestFile' value=\"" . htmlspecialchars( $this->mDestFile ) . "\" />
 671+ <input type='hidden' name='wpDestFile' value=\"" . htmlspecialchars( $this->mDesiredDestName ) . "\" />
692672 <input type='hidden' name='wpWatchthis' value=\"" . htmlspecialchars( intval( $this->mWatchthis ) ) . "\" />
693673 {$copyright}
694674 <table border='0'>
@@ -737,7 +717,7 @@
738718 "<span class='error'>{$msg}</span>\n" );
739719 }
740720 $wgOut->addHTML( '<div id="uploadtext">' );
741 - $wgOut->addWikiText( wfMsgNoTrans( 'uploadtext', $this->mDestFile ) );
 721+ $wgOut->addWikiText( wfMsgNoTrans( 'uploadtext', $this->mDesiredDestName ) );
742722 $wgOut->addHTML( '</div>' );
743723
744724 $sourcefilename = wfMsgHtml( 'sourcefilename' );
@@ -755,35 +735,44 @@
756736 $titleObj = SpecialPage::getTitleFor( 'Upload' );
757737 $action = $titleObj->escapeLocalURL();
758738
759 - $encDestFile = htmlspecialchars( $this->mDestFile );
 739+ $encDestName = htmlspecialchars( $this->mDesiredDestName );
760740
761741 $watchChecked =
762742 ( $wgUser->getOption( 'watchdefault' ) ||
763 - ( $wgUser->getOption( 'watchcreations' ) && $this->mDestFile == '' ) )
 743+ ( $wgUser->getOption( 'watchcreations' ) && $this->mDesiredDestName == '' ) )
764744 ? 'checked="checked"'
765745 : '';
766746
767747 // Prepare form for upload or upload/copy
768748 if( $wgAllowCopyUploads && $wgUser->isAllowed( 'upload_by_url' ) ) {
769749 $filename_form =
770 - "<input type='radio' id='wpSourceTypeFile' name='wpSourceType' value='file' onchange='toggle_element_activation(\"wpUploadFileURL\",\"wpUploadFile\")' checked />" .
771 - "<input tabindex='1' type='file' name='wpUploadFile' id='wpUploadFile' onfocus='toggle_element_activation(\"wpUploadFileURL\",\"wpUploadFile\");toggle_element_check(\"wpSourceTypeFile\",\"wpSourceTypeURL\")'" .
772 - ($this->mDestFile?"":"onchange='fillDestFilename(\"wpUploadFile\")' ") . "size='40' />" .
 750+ "<input type='radio' id='wpSourceTypeFile' name='wpSourceType' value='file' " .
 751+ "onchange='toggle_element_activation(\"wpUploadFileURL\",\"wpUploadFile\")' checked />" .
 752+ "<input tabindex='1' type='file' name='wpUploadFile' id='wpUploadFile' " .
 753+ "onfocus='" .
 754+ "toggle_element_activation(\"wpUploadFileURL\",\"wpUploadFile\");" .
 755+ "toggle_element_check(\"wpSourceTypeFile\",\"wpSourceTypeURL\")'" .
 756+ ($this->mDesiredDestName?"":"onchange='fillDestFilename(\"wpUploadFile\")' ") . "size='40' />" .
773757 wfMsgHTML( 'upload_source_file' ) . "<br/>" .
774 - "<input type='radio' id='wpSourceTypeURL' name='wpSourceType' value='web' onchange='toggle_element_activation(\"wpUploadFile\",\"wpUploadFileURL\")' />" .
775 - "<input tabindex='1' type='text' name='wpUploadFileURL' id='wpUploadFileURL' onfocus='toggle_element_activation(\"wpUploadFile\",\"wpUploadFileURL\");toggle_element_check(\"wpSourceTypeURL\",\"wpSourceTypeFile\")'" .
776 - ($this->mDestFile?"":"onchange='fillDestFilename(\"wpUploadFileURL\")' ") . "size='40' DISABLED />" .
 758+ "<input type='radio' id='wpSourceTypeURL' name='wpSourceType' value='web' " .
 759+ "onchange='toggle_element_activation(\"wpUploadFile\",\"wpUploadFileURL\")' />" .
 760+ "<input tabindex='1' type='text' name='wpUploadFileURL' id='wpUploadFileURL' " .
 761+ "onfocus='" .
 762+ "toggle_element_activation(\"wpUploadFile\",\"wpUploadFileURL\");" .
 763+ "toggle_element_check(\"wpSourceTypeURL\",\"wpSourceTypeFile\")'" .
 764+ ($this->mDesiredDestName?"":"onchange='fillDestFilename(\"wpUploadFileURL\")' ") . "size='40' DISABLED />" .
777765 wfMsgHtml( 'upload_source_url' ) ;
778766 } else {
779767 $filename_form =
780768 "<input tabindex='1' type='file' name='wpUploadFile' id='wpUploadFile' " .
781 - ($this->mDestFile?"":"onchange='fillDestFilename(\"wpUploadFile\")' ") .
 769+ ($this->mDesiredDestName?"":"onchange='fillDestFilename(\"wpUploadFile\")' ") .
782770 "size='40' />" .
783771 "<input type='hidden' name='wpSourceType' value='file' />" ;
784772 }
 773+ $encComment = htmlspecialchars( $this->mComment );
785774
786 - $wgOut->addHTML( "
787 - <form id='upload' method='post' enctype='multipart/form-data' action=\"$action\">
 775+ $wgOut->addHTML( <<<EOT
 776+ <form id='upload' method='post' enctype='multipart/form-data' action="$action">
788777 <table border='0'>
789778 <tr>
790779 {$this->uploadFormTextTop}
@@ -795,17 +784,20 @@
796785 <tr>
797786 <td align='right'><label for='wpDestFile'>{$destfilename}:</label></td>
798787 <td align='left'>
799 - <input tabindex='2' type='text' name='wpDestFile' id='wpDestFile' size='40' value=\"$encDestFile\" />
 788+ <input tabindex='2' type='text' name='wpDestFile' id='wpDestFile' size='40' value="$encDestName" />
800789 </td>
801790 </tr>
802791 <tr>
803792 <td align='right'><label for='wpUploadDescription'>{$summary}</label></td>
804793 <td align='left'>
805 - <textarea tabindex='3' name='wpUploadDescription' id='wpUploadDescription' rows='6' cols='{$cols}'{$ew}>" . htmlspecialchars( $this->mUploadDescription ) . "</textarea>
 794+ <textarea tabindex='3' name='wpUploadDescription' id='wpUploadDescription' rows='6'
 795+ cols='{$cols}'{$ew}>$encComment</textarea>
806796 {$this->uploadFormTextAfterSummary}
807797 </td>
808798 </tr>
809 - <tr>" );
 799+ <tr>
 800+EOT
 801+ );
810802
811803 if ( $licenseshtml != '' ) {
812804 global $wgStylePath;
@@ -826,17 +818,19 @@
827819
828820 if ( $wgUseCopyrightUpload ) {
829821 $filestatus = wfMsgHtml ( 'filestatus' );
830 - $copystatus = htmlspecialchars( $this->mUploadCopyStatus );
 822+ $copystatus = htmlspecialchars( $this->mCopyrightStatus );
831823 $filesource = wfMsgHtml ( 'filesource' );
832 - $uploadsource = htmlspecialchars( $this->mUploadSource );
 824+ $uploadsource = htmlspecialchars( $this->mCopyrightSource );
833825
834826 $wgOut->addHTML( "
835827 <td align='right' nowrap='nowrap'><label for='wpUploadCopyStatus'>$filestatus:</label></td>
836 - <td><input tabindex='5' type='text' name='wpUploadCopyStatus' id='wpUploadCopyStatus' value=\"$copystatus\" size='40' /></td>
 828+ <td><input tabindex='5' type='text' name='wpUploadCopyStatus' id='wpUploadCopyStatus'
 829+ value=\"$copystatus\" size='40' /></td>
837830 </tr>
838831 <tr>
839832 <td align='right'><label for='wpUploadCopyStatus'>$filesource:</label></td>
840 - <td><input tabindex='6' type='text' name='wpUploadSource' id='wpUploadCopyStatus' value=\"$uploadsource\" size='40' /></td>
 833+ <td><input tabindex='6' type='text' name='wpUploadSource' id='wpUploadCopyStatus'
 834+ value=\"$uploadsource\" size='40' /></td>
841835 </tr>
842836 <tr>
843837 ");
@@ -927,8 +921,6 @@
928922 $magic=& MimeMagic::singleton();
929923 $mime= $magic->guessMimeType($tmpfile,false);
930924
931 - $fname= "SpecialUpload::verify";
932 -
933925 #check mime type, if desired
934926 global $wgVerifyMimeType;
935927 if ($wgVerifyMimeType) {
@@ -959,7 +951,7 @@
960952 return new WikiErrorMsg( 'uploadvirus', htmlspecialchars($virus) );
961953 }
962954
963 - wfDebug( "$fname: all clear; passing.\n" );
 955+ wfDebug( __METHOD__.": all clear; passing.\n" );
964956 return true;
965957 }
966958
@@ -971,45 +963,46 @@
972964 * @return bool
973965 */
974966 function verifyExtension( $mime, $extension ) {
975 - $fname = 'SpecialUpload::verifyExtension';
976 -
977967 $magic =& MimeMagic::singleton();
978968
979969 if ( ! $mime || $mime == 'unknown' || $mime == 'unknown/unknown' )
980970 if ( ! $magic->isRecognizableExtension( $extension ) ) {
981 - wfDebug( "$fname: passing file with unknown detected mime type; unrecognized extension '$extension', can't verify\n" );
 971+ wfDebug( __METHOD__.": passing file with unknown detected mime type; " .
 972+ "unrecognized extension '$extension', can't verify\n" );
982973 return true;
983974 } else {
984 - wfDebug( "$fname: rejecting file with unknown detected mime type; recognized extension '$extension', so probably invalid file\n" );
 975+ wfDebug( __METHOD__.": rejecting file with unknown detected mime type; ".
 976+ "recognized extension '$extension', so probably invalid file\n" );
985977 return false;
986978 }
987979
988980 $match= $magic->isMatchingExtension($extension,$mime);
989981
990982 if ($match===NULL) {
991 - wfDebug( "$fname: no file extension known for mime type $mime, passing file\n" );
 983+ wfDebug( __METHOD__.": no file extension known for mime type $mime, passing file\n" );
992984 return true;
993985 } elseif ($match===true) {
994 - wfDebug( "$fname: mime type $mime matches extension $extension, passing file\n" );
 986+ wfDebug( __METHOD__.": mime type $mime matches extension $extension, passing file\n" );
995987
996988 #TODO: if it's a bitmap, make sure PHP or ImageMagic resp. can handle it!
997989 return true;
998990
999991 } else {
1000 - wfDebug( "$fname: mime type $mime mismatches file extension $extension, rejecting file\n" );
 992+ wfDebug( __METHOD__.": mime type $mime mismatches file extension $extension, rejecting file\n" );
1001993 return false;
1002994 }
1003995 }
1004996
1005 - /** Heuristig for detecting files that *could* contain JavaScript instructions or
1006 - * things that may look like HTML to a browser and are thus
1007 - * potentially harmful. The present implementation will produce false positives in some situations.
1008 - *
1009 - * @param string $file Pathname to the temporary upload file
1010 - * @param string $mime The mime type of the file
1011 - * @param string $extension The extension of the file
1012 - * @return bool true if the file contains something looking like embedded scripts
1013 - */
 997+ /**
 998+ * Heuristic for detecting files that *could* contain JavaScript instructions or
 999+ * things that may look like HTML to a browser and are thus
 1000+ * potentially harmful. The present implementation will produce false positives in some situations.
 1001+ *
 1002+ * @param string $file Pathname to the temporary upload file
 1003+ * @param string $mime The mime type of the file
 1004+ * @param string $extension The extension of the file
 1005+ * @return bool true if the file contains something looking like embedded scripts
 1006+ */
10141007 function detectScript($file, $mime, $extension) {
10151008 global $wgAllowTitlesInSVG;
10161009
@@ -1098,93 +1091,103 @@
10991092 return false;
11001093 }
11011094
1102 - /** Generic wrapper function for a virus scanner program.
1103 - * This relies on the $wgAntivirus and $wgAntivirusSetup variables.
1104 - * $wgAntivirusRequired may be used to deny upload if the scan fails.
1105 - *
1106 - * @param string $file Pathname to the temporary upload file
1107 - * @return mixed false if not virus is found, NULL if the scan fails or is disabled,
1108 - * or a string containing feedback from the virus scanner if a virus was found.
1109 - * If textual feedback is missing but a virus was found, this function returns true.
1110 - */
 1095+ /**
 1096+ * Generic wrapper function for a virus scanner program.
 1097+ * This relies on the $wgAntivirus and $wgAntivirusSetup variables.
 1098+ * $wgAntivirusRequired may be used to deny upload if the scan fails.
 1099+ *
 1100+ * @param string $file Pathname to the temporary upload file
 1101+ * @return mixed false if not virus is found, NULL if the scan fails or is disabled,
 1102+ * or a string containing feedback from the virus scanner if a virus was found.
 1103+ * If textual feedback is missing but a virus was found, this function returns true.
 1104+ */
11111105 function detectVirus($file) {
11121106 global $wgAntivirus, $wgAntivirusSetup, $wgAntivirusRequired, $wgOut;
11131107
1114 - $fname= "SpecialUpload::detectVirus";
1115 -
1116 - if (!$wgAntivirus) { #disabled?
1117 - wfDebug("$fname: virus scanner disabled\n");
1118 -
 1108+ if ( !$wgAntivirus ) {
 1109+ wfDebug( __METHOD__.": virus scanner disabled\n");
11191110 return NULL;
11201111 }
11211112
1122 - if (!$wgAntivirusSetup[$wgAntivirus]) {
1123 - wfDebug("$fname: unknown virus scanner: $wgAntivirus\n");
1124 -
1125 - $wgOut->addHTML( "<div class='error'>Bad configuration: unknown virus scanner: <i>$wgAntivirus</i></div>\n" ); #LOCALIZE
1126 -
 1113+ if ( !$wgAntivirusSetup[$wgAntivirus] ) {
 1114+ wfDebug( __METHOD__.": unknown virus scanner: $wgAntivirus\n" );
 1115+ # @TODO: localise
 1116+ $wgOut->addHTML( "<div class='error'>Bad configuration: unknown virus scanner: <i>$wgAntivirus</i></div>\n" );
11271117 return "unknown antivirus: $wgAntivirus";
11281118 }
11291119
1130 - #look up scanner configuration
1131 - $virus_scanner= $wgAntivirusSetup[$wgAntivirus]["command"]; #command pattern
1132 - $virus_scanner_codes= $wgAntivirusSetup[$wgAntivirus]["codemap"]; #exit-code map
1133 - $msg_pattern= $wgAntivirusSetup[$wgAntivirus]["messagepattern"]; #message pattern
 1120+ # look up scanner configuration
 1121+ $command = $wgAntivirusSetup[$wgAntivirus]["command"];
 1122+ $exitCodeMap = $wgAntivirusSetup[$wgAntivirus]["codemap"];
 1123+ $msgPattern = isset( $wgAntivirusSetup[$wgAntivirus]["messagepattern"] ) ?
 1124+ $wgAntivirusSetup[$wgAntivirus]["messagepattern"] : null;
11341125
1135 - $scanner= $virus_scanner; #copy, so we can resolve the pattern
 1126+ if ( strpos( $command,"%f" ) === false ) {
 1127+ # simple pattern: append file to scan
 1128+ $command .= " " . wfEscapeShellArg( $file );
 1129+ } else {
 1130+ # complex pattern: replace "%f" with file to scan
 1131+ $command = str_replace( "%f", wfEscapeShellArg( $file ), $command );
 1132+ }
11361133
1137 - if (strpos($scanner,"%f")===false) $scanner.= " ".wfEscapeShellArg($file); #simple pattern: append file to scan
1138 - else $scanner= str_replace("%f",wfEscapeShellArg($file),$scanner); #complex pattern: replace "%f" with file to scan
 1134+ wfDebug( __METHOD__.": running virus scan: $command \n" );
11391135
1140 - wfDebug("$fname: running virus scan: $scanner \n");
 1136+ # execute virus scanner
 1137+ $exitCode = false;
11411138
1142 - #execute virus scanner
1143 - $code= false;
1144 -
11451139 #NOTE: there's a 50 line workaround to make stderr redirection work on windows, too.
11461140 # that does not seem to be worth the pain.
11471141 # Ask me (Duesentrieb) about it if it's ever needed.
11481142 $output = array();
1149 - if (wfIsWindows()) exec("$scanner",$output,$code);
1150 - else exec("$scanner 2>&1",$output,$code);
 1143+ if ( wfIsWindows() ) {
 1144+ exec( "$command", $output, $exitCode );
 1145+ } else {
 1146+ exec( "$command 2>&1", $output, $exitCode );
 1147+ }
11511148
1152 - $exit_code= $code; #remember for user feedback
1153 -
1154 - if ($virus_scanner_codes) { #map exit code to AV_xxx constants.
1155 - if (isset($virus_scanner_codes[$code])) {
1156 - $code= $virus_scanner_codes[$code]; # explicit mapping
1157 - } else if (isset($virus_scanner_codes["*"])) {
1158 - $code= $virus_scanner_codes["*"]; # fallback mapping
 1149+ # map exit code to AV_xxx constants.
 1150+ $mappedCode = $exitCode;
 1151+ if ( $exitCodeMap ) {
 1152+ if ( isset( $exitCodeMap[$exitCode] ) ) {
 1153+ $mappedCode = $exitCodeMap[$exitCode];
 1154+ } elseif ( isset( $exitCodeMap["*"] ) ) {
 1155+ $mappedCode = $exitCodeMap["*"];
11591156 }
11601157 }
11611158
1162 - if ($code===AV_SCAN_FAILED) { #scan failed (code was mapped to false by $virus_scanner_codes)
1163 - wfDebug("$fname: failed to scan $file (code $exit_code).\n");
 1159+ if ( $mappedCode === AV_SCAN_FAILED ) {
 1160+ # scan failed (code was mapped to false by $exitCodeMap)
 1161+ wfDebug( __METHOD__.": failed to scan $file (code $exitCode).\n" );
11641162
1165 - if ($wgAntivirusRequired) { return "scan failed (code $exit_code)"; }
1166 - else { return NULL; }
1167 - }
1168 - else if ($code===AV_SCAN_ABORTED) { #scan failed because filetype is unknown (probably imune)
1169 - wfDebug("$fname: unsupported file type $file (code $exit_code).\n");
 1163+ if ( $wgAntivirusRequired ) {
 1164+ return "scan failed (code $exitCode)";
 1165+ } else {
 1166+ return NULL;
 1167+ }
 1168+ } else if ( $mappedCode === AV_SCAN_ABORTED ) {
 1169+ # scan failed because filetype is unknown (probably imune)
 1170+ wfDebug( __METHOD__.": unsupported file type $file (code $exitCode).\n" );
11701171 return NULL;
1171 - }
1172 - else if ($code===AV_NO_VIRUS) {
1173 - wfDebug("$fname: file passed virus scan.\n");
1174 - return false; #no virus found
1175 - }
1176 - else {
1177 - $output= join("\n",$output);
1178 - $output= trim($output);
 1172+ } else if ( $mappedCode === AV_NO_VIRUS ) {
 1173+ # no virus found
 1174+ wfDebug( __METHOD__.": file passed virus scan.\n" );
 1175+ return false;
 1176+ } else {
 1177+ $output = join( "\n", $output );
 1178+ $output = trim( $output );
11791179
1180 - if (!$output) $output= true; #if there's no output, return true
1181 - else if ($msg_pattern) {
1182 - $groups= array();
1183 - if (preg_match($msg_pattern,$output,$groups)) {
1184 - if ($groups[1]) $output= $groups[1];
 1180+ if ( !$output ) {
 1181+ $output = true; #if there's no output, return true
 1182+ } elseif ( $msgPattern ) {
 1183+ $groups = array();
 1184+ if ( preg_match( $msgPattern, $output, $groups ) ) {
 1185+ if ( $groups[1] ) {
 1186+ $output = $groups[1];
 1187+ }
11851188 }
11861189 }
11871190
1188 - wfDebug("$fname: FOUND VIRUS! scanner feedback: $output");
 1191+ wfDebug( __METHOD__.": FOUND VIRUS! scanner feedback: $output" );
11891192 return $output;
11901193 }
11911194 }
@@ -1198,7 +1201,7 @@
11991202 * @access private
12001203 */
12011204 function checkMacBinary() {
1202 - $macbin = new MacBinary( $this->mUploadTempName );
 1205+ $macbin = new MacBinary( $this->mTempPath );
12031206 if( $macbin->isValid() ) {
12041207 $dataFile = tempnam( wfTempDir(), "WikiMacBinary" );
12051208 $dataHandle = fopen( $dataFile, 'wb' );
@@ -1206,8 +1209,8 @@
12071210 wfDebug( "SpecialUpload::checkMacBinary: Extracting MacBinary data fork to $dataFile\n" );
12081211 $macbin->extractData( $dataHandle );
12091212
1210 - $this->mUploadTempName = $dataFile;
1211 - $this->mUploadSize = $macbin->dataForkLength();
 1213+ $this->mTempPath = $dataFile;
 1214+ $this->mFileSize = $macbin->dataForkLength();
12121215
12131216 // We'll have to manually remove the new file if it's not kept.
12141217 $this->mRemoveTempFile = true;
@@ -1221,9 +1224,9 @@
12221225 * @access private
12231226 */
12241227 function cleanupTempFile() {
1225 - if( $this->mRemoveTempFile && file_exists( $this->mUploadTempName ) ) {
1226 - wfDebug( "SpecialUpload::cleanupTempFile: Removing temporary file $this->mUploadTempName\n" );
1227 - unlink( $this->mUploadTempName );
 1228+ if ( $this->mRemoveTempFile && file_exists( $this->mTempPath ) ) {
 1229+ wfDebug( "SpecialUpload::cleanupTempFile: Removing temporary file {$this->mTempPath}\n" );
 1230+ unlink( $this->mTempPath );
12281231 }
12291232 }
12301233
@@ -1296,5 +1299,30 @@
12971300 $wgOut->enableClientCache( false );
12981301 $wgOut->addWikiText( $error->getMessage() );
12991302 }
 1303+
 1304+ /**
 1305+ * Get the initial image page text based on a comment and optional file status information
 1306+ */
 1307+ static function getInitialPageText( $comment, $license, $copyStatus, $source ) {
 1308+ global $wgUseCopyrightUpload;
 1309+ if ( $wgUseCopyrightUpload ) {
 1310+ if ( $license != '' ) {
 1311+ $licensetxt = '== ' . wfMsgForContent( 'license' ) . " ==\n" . '{{' . $license . '}}' . "\n";
 1312+ }
 1313+ $pageText = '== ' . wfMsg ( 'filedesc' ) . " ==\n" . $comment . "\n" .
 1314+ '== ' . wfMsgForContent ( 'filestatus' ) . " ==\n" . $copyStatus . "\n" .
 1315+ "$licensetxt" .
 1316+ '== ' . wfMsgForContent ( 'filesource' ) . " ==\n" . $source ;
 1317+ } else {
 1318+ if ( $license != '' ) {
 1319+ $filedesc = $comment == '' ? '' : '== ' . wfMsg ( 'filedesc' ) . " ==\n" . $comment . "\n";
 1320+ $pageText = $filedesc .
 1321+ '== ' . wfMsgForContent ( 'license' ) . " ==\n" . '{{' . $license . '}}' . "\n";
 1322+ } else {
 1323+ $pageText = $comment;
 1324+ }
 1325+ }
 1326+ return $pageText;
 1327+ }
13001328 }
13011329 ?>
Index: branches/phase3_rev_deleted/includes/RecentChange.php
@@ -295,11 +295,9 @@
296296 public static function notifyNew( $timestamp, &$title, $minor, &$user, $comment, $bot = 'default',
297297 $ip='', $size = 0, $newId = 0 )
298298 {
299 - if ( !$ip ) {
 299+ if( !$ip ) {
300300 $ip = wfGetIP();
301 - if ( !$ip ) {
302 - $ip = '';
303 - }
 301+ if( !$ip ) $ip = '';
304302 }
305303 if ( $bot === 'default' ) {
306304 $bot = $user->isAllowed( 'bot' );
@@ -347,11 +345,9 @@
348346 # Makes an entry in the database corresponding to a rename
349347 /*static*/ function notifyMove( $timestamp, &$oldTitle, &$newTitle, &$user, $comment, $ip='', $overRedir = false )
350348 {
351 - if ( !$ip ) {
 349+ if( !$ip ) {
352350 $ip = wfGetIP();
353 - if ( !$ip ) {
354 - $ip = '';
355 - }
 351+ if( !$ip ) $ip = '';
356352 }
357353
358354 $rc = new RecentChange;
@@ -404,16 +400,17 @@
405401 /*static*/ function notifyLog( $timestamp, &$title, &$user, $comment, $ip='',
406402 $type, $action, $target, $logComment, $params, $newId=0 )
407403 {
408 - if ( !$ip ) {
 404+ if( !$ip ) {
409405 $ip = wfGetIP();
410 - if ( !$ip ) $ip = '';
 406+ if( !$ip ) $ip = '';
411407 }
 408+
412409 $rc = new RecentChange;
413410 $rc->mAttribs = array(
414411 'rc_timestamp' => $timestamp,
415412 'rc_cur_time' => $timestamp,
416 - 'rc_namespace' => $title->getNamespace(),
417 - 'rc_title' => $title->getDBkey(),
 413+ 'rc_namespace' => $target->getNamespace(),
 414+ 'rc_title' => $target->getDBkey(),
418415 'rc_type' => RC_LOG,
419416 'rc_minor' => 0,
420417 'rc_cur_id' => $title->getArticleID(),
Index: branches/phase3_rev_deleted/includes/SearchMySQL.php
@@ -200,6 +200,10 @@
201201 return new SearchResult( $row );
202202 }
203203 }
 204+
 205+ function free() {
 206+ $this->mResultSet->free();
 207+ }
204208 }
205209
206210 ?>
Index: branches/phase3_rev_deleted/includes/SpecialPreferences.php
@@ -241,11 +241,18 @@
242242 }
243243
244244 # Validate the signature and clean it up as needed
245 - if( $this->mToggles['fancysig'] ) {
 245+ global $wgMaxSigChars;
 246+ if( strlen( $this->mNick ) > $wgMaxSigChars ) {
 247+ global $wgLang;
 248+ $this->mainPrefsForm( 'error',
 249+ wfMsg( 'badsiglength', $wgLang->formatNum( $wgMaxSigChars ) ) );
 250+ return;
 251+ } elseif( $this->mToggles['fancysig'] ) {
246252 if( Parser::validateSig( $this->mNick ) !== false ) {
247253 $this->mNick = $wgParser->cleanSig( $this->mNick );
248254 } else {
249255 $this->mainPrefsForm( 'error', wfMsg( 'badsig' ) );
 256+ return;
250257 }
251258 } else {
252259 // When no fancy sig used, make sure ~{3,5} get removed.
@@ -602,8 +609,14 @@
603610 );
604611 }
605612
606 - global $wgParser;
607 - if( !empty( $this->mToggles['fancysig'] ) &&
 613+ global $wgParser, $wgMaxSigChars;
 614+ if( strlen( $this->mNick ) > $wgMaxSigChars ) {
 615+ $invalidSig = $this->tableRow(
 616+ '&nbsp;',
 617+ Xml::element( 'span', array( 'class' => 'error' ),
 618+ wfMsg( 'badsiglength', $wgLang->formatNum( $wgMaxSigChars ) ) )
 619+ );
 620+ } elseif( !empty( $this->mToggles['fancysig'] ) &&
608621 false === $wgParser->validateSig( $this->mNick ) ) {
609622 $invalidSig = $this->tableRow(
610623 '&nbsp;',
@@ -616,7 +629,14 @@
617630 $wgOut->addHTML(
618631 $this->tableRow(
619632 Xml::label( wfMsg( 'yournick' ), 'wpNick' ),
620 - Xml::input( 'wpNick', 25, $this->mNick, array( 'id' => 'wpNick' ) )
 633+ Xml::input( 'wpNick', 25, $this->mNick,
 634+ array(
 635+ 'id' => 'wpNick',
 636+ // Note: $wgMaxSigChars is currently enforced in UTF-8 bytes,
 637+ // but 'maxlength' attribute is enforced in characters.
 638+ // It's still possible to put in an overlong string
 639+ // 'legitimately' by typing non-ASCII chars.
 640+ 'maxlength' => $wgMaxSigChars ) )
621641 ) .
622642 $invalidSig .
623643 $this->tableRow( '&nbsp;', $this->getToggle( 'fancysig' ) )
@@ -949,8 +969,8 @@
950970 # Misc
951971 #
952972 $wgOut->addHTML('<fieldset><legend>' . wfMsg('prefs-misc') . '</legend>');
953 - $wgOut->addHTML( wfInputLabel( wfMsg( 'stubthreshold' ),
954 - 'wpStubs', 'wpStubs', 6, $this->mStubs ) );
 973+ $wgOut->addHtml( '<label for="wpStubs">' . wfMsg( 'stub-threshold' ) . '</label>&nbsp;' );
 974+ $wgOut->addHtml( Xml::input( 'wpStubs', 6, $this->mStubs, array( 'id' => 'wpStubs' ) ) );
955975 $msgUnderline = htmlspecialchars( wfMsg ( 'tog-underline' ) );
956976 $msgUnderlinenever = htmlspecialchars( wfMsg ( 'underline-never' ) );
957977 $msgUnderlinealways = htmlspecialchars( wfMsg ( 'underline-always' ) );
Index: branches/phase3_rev_deleted/includes/SpecialUserlogin.php
@@ -265,6 +265,11 @@
266266 $this->mainLoginForm( wfMsg( 'passwordtooshort', $wgMinimalPasswordLength ) );
267267 return false;
268268 }
 269+
 270+ # Set some additional data so the AbortNewAccount hook can be
 271+ # used for more than just username validation
 272+ $u->setEmail( $this->mEmail );
 273+ $u->setRealName( $this->mRealName );
269274
270275 $abortError = '';
271276 if( !wfRunHooks( 'AbortNewAccount', array( $u, &$abortError ) ) ) {
Index: branches/phase3_rev_deleted/includes/SpecialWhatlinkshere.php
@@ -230,12 +230,14 @@
231231 $wgOut->addHTML( ' (' . implode( ', ', $props ) . ') ' );
232232 }
233233
234 - //add whatlinkshere link
235 - $whatlink = $this->skin->makeKnownLinkObj(
236 - SpecialPage::getTitleFor( 'Whatlinkshere', $nt->getPrefixedDBkey() ),
237 - wfMsgHtml( 'whatlinkshere-links' ) );
238 - $wgOut->addHTML(" ($whatlink)" );
239 -
 234+ # Space for utilities links, with a what-links-here link provided
 235+ $wlh = $this->skin->makeKnownLinkObj(
 236+ SpecialPage::getTitleFor( 'Whatlinkshere' ),
 237+ wfMsgHtml( 'whatlinkshere-links' ),
 238+ 'target=' . $nt->getPrefixedUrl()
 239+ );
 240+ $wgOut->addHtml( ' <span class="mw-whatlinkshere-tools">(' . $wlh . ')</span>' );
 241+
240242 if ( $row->page_is_redirect ) {
241243 if ( $level < 2 ) {
242244 $this->showIndirectLinks( $level + 1, $nt, 500 );
Index: branches/phase3_rev_deleted/includes/SpecialRecentchanges.php
@@ -269,8 +269,6 @@
270270 }
271271
272272 function rcFilterByCategories ( &$rows , $categories , $any ) {
273 - require_once ( 'Categoryfinder.php' ) ;
274 -
275273 # Filter categories
276274 $cats = array () ;
277275 foreach ( $categories AS $cat ) {
Index: branches/phase3_rev_deleted/includes/SpecialProtectedpages.php
@@ -147,6 +147,11 @@
148148 foreach( $wgRestrictionTypes as $type ) {
149149 $text = wfMsg("restriction-$type");
150150 $m[$text] = $type;
 151+ if( $type=='edit' ) {
 152+ // Upload rights for images, a subtype of edit
 153+ $text = wfMsg("restriction-upload");
 154+ $m[$text] = 'upload';
 155+ }
151156 }
152157
153158 // Third pass generates sorted XHTML content
Index: branches/phase3_rev_deleted/includes/SearchEngine.php
@@ -322,6 +322,14 @@
323323 function next() {
324324 return false;
325325 }
 326+
 327+ /**
 328+ * Frees the result set, if applicable.
 329+ * @ access public
 330+ */
 331+ function free() {
 332+ // ...
 333+ }
326334 }
327335
328336
Index: branches/phase3_rev_deleted/includes/Xml.php
@@ -100,15 +100,8 @@
101101 */
102102 public static function namespaceSelector($selected = '', $allnamespaces = null, $includehidden=false) {
103103 global $wgContLang;
104 - if( $selected !== '' ) {
105 - if( is_null( $selected ) ) {
106 - // No namespace selected; let exact match work without hitting Main
107 - $selected = '';
108 - } else {
109 - // Let input be numeric strings without breaking the empty match.
110 - $selected = intval( $selected );
111 - }
112 - }
 104+ if( is_null( $selected ) )
 105+ $selected = '';
113106 $s = "\n<select id='namespace' name='namespace' class='namespaceselector'>\n";
114107 $arr = $wgContLang->getFormattedNamespaces();
115108 if( !is_null($allnamespaces) ) {
Index: branches/phase3_rev_deleted/includes/Title.php
@@ -47,6 +47,7 @@
4848 var $mTextform; # Text form (spaces not underscores) of the main part
4949 var $mUrlform; # URL-encoded form of the main part
5050 var $mDbkeyform; # Main part with underscores
 51+ var $mUserCaseDBKey; # DB key with the initial letter in the case specified by the user
5152 var $mNamespace; # Namespace index, i.e. one of the NS_xxxx constants
5253 var $mInterwiki; # Interwiki prefix (or null string)
5354 var $mFragment; # Title fragment (i.e. the bit after the #)
@@ -557,6 +558,12 @@
558559 return $wgContLang->getNsText( $this->mNamespace );
559560 }
560561 /**
 562+ * Get the DB key with the initial letter case as specified by the user
 563+ */
 564+ function getUserCaseDBKey() {
 565+ return $this->mUserCaseDBKey;
 566+ }
 567+ /**
561568 * Get the namespace text of the subject (rather than talk) page
562569 * @return string
563570 */
@@ -1749,6 +1756,7 @@
17501757 * Don't force it for interwikis, since the other
17511758 * site might be case-sensitive.
17521759 */
 1760+ $this->mUserCaseDBKey = $dbkey;
17531761 if( $wgCapitalLinks && $this->mInterwiki == '') {
17541762 $dbkey = $wgContLang->ucfirst( $dbkey );
17551763 }
Index: branches/phase3_rev_deleted/includes/EditPage.php
@@ -410,9 +410,10 @@
411411 }
412412 }
413413
414 - if(!$this->mTitle->getArticleID() && ('initial' == $this->formtype || $this->firsttime )) { # new article
 414+ # Show applicable editing introductions
 415+ if( $this->formtype == 'initial' || $this->firsttime )
415416 $this->showIntro();
416 - }
 417+
417418 if( $this->mTitle->isTalkPage() ) {
418419 $wgOut->addWikiText( wfMsg( 'talkpagetext' ) );
419420 }
@@ -585,27 +586,41 @@
586587 return $this->mTokenOk;
587588 }
588589
589 - /** */
590 - function showIntro() {
 590+ /**
 591+ * Show all applicable editing introductions
 592+ */
 593+ private function showIntro() {
591594 global $wgOut, $wgUser;
592 - $addstandardintro=true;
593 - if($this->editintro) {
594 - $introtitle=Title::newFromText($this->editintro);
595 - if(isset($introtitle) && $introtitle->userCanRead()) {
596 - $rev=Revision::newFromTitle($introtitle);
597 - if($rev) {
598 - $wgOut->addSecondaryWikiText($rev->getText());
599 - $addstandardintro=false;
600 - }
601 - }
602 - }
603 - if($addstandardintro) {
604 - if ( $wgUser->isLoggedIn() )
 595+ if( !$this->showCustomIntro() && !$this->mTitle->exists() ) {
 596+ if( $wgUser->isLoggedIn() ) {
605597 $wgOut->addWikiText( wfMsg( 'newarticletext' ) );
606 - else
 598+ } else {
607599 $wgOut->addWikiText( wfMsg( 'newarticletextanon' ) );
 600+ }
 601+ $this->showDeletionLog( $wgOut );
608602 }
609603 }
 604+
 605+ /**
 606+ * Attempt to show a custom editing introduction, if supplied
 607+ *
 608+ * @return bool
 609+ */
 610+ private function showCustomIntro() {
 611+ if( $this->editintro ) {
 612+ $title = Title::newFromText( $this->editintro );
 613+ if( $title instanceof Title && $title->exists() && $title->userCanRead() ) {
 614+ global $wgOut;
 615+ $revision = Revision::newFromTitle( $title );
 616+ $wgOut->addSecondaryWikiText( $revision->getText() );
 617+ return true;
 618+ } else {
 619+ return false;
 620+ }
 621+ } else {
 622+ return false;
 623+ }
 624+ }
610625
611626 /**
612627 * Attempt submission
@@ -1089,8 +1104,7 @@
10901105 }
10911106
10921107 if ( 'diff' == $this->formtype ) {
1093 - $wgOut->addStyle( 'common/diff.css' );
1094 - $wgOut->addHTML( $this->getDiff() );
 1108+ $this->showDiff();
10951109 }
10961110 }
10971111
@@ -1116,7 +1130,7 @@
11171131 if( !$this->preview && !$this->diff ) {
11181132 $wgOut->setOnloadHandler( 'document.editform.wpTextbox1.focus()' );
11191133 }
1120 - $templates = ($this->preview || $this->section) ? $this->mPreviewTemplates : $this->mArticle->getUsedTemplates();
 1134+ $templates = ($this->preview || $this->section != '') ? $this->mPreviewTemplates : $this->mArticle->getUsedTemplates();
11211135 $formattedtemplates = $sk->formatTemplates( $templates, $this->preview, $this->section != '');
11221136
11231137 global $wgUseMetadataEdit ;
@@ -1272,8 +1286,7 @@
12731287 }
12741288
12751289 if ( $this->formtype == 'diff') {
1276 - $wgOut->addStyle( 'common/diff.css' );
1277 - $wgOut->addHTML( $this->getDiff() );
 1290+ $this->showDiff();
12781291 }
12791292
12801293 }
@@ -1895,10 +1908,8 @@
18961909 *
18971910 * If this is a section edit, we'll replace the section as for final
18981911 * save and then make a comparison.
1899 - *
1900 - * @return string HTML
19011912 */
1902 - function getDiff() {
 1913+ function showDiff() {
19031914 $oldtext = $this->mArticle->fetchContent();
19041915 $newtext = $this->mArticle->replaceSection(
19051916 $this->section, $this->textbox1, $this->summary, $this->edittime );
@@ -1909,11 +1920,13 @@
19101921 $de = new DifferenceEngine( $this->mTitle );
19111922 $de->setText( $oldtext, $newtext );
19121923 $difftext = $de->getDiff( $oldtitle, $newtitle );
 1924+ $de->showDiffStyle();
19131925 } else {
19141926 $difftext = '';
19151927 }
19161928
1917 - return '<div id="wikiDiff">' . $difftext . '</div>';
 1929+ global $wgOut;
 1930+ $wgOut->addHtml( '<div id="wikiDiff">' . $difftext . '</div>' );
19181931 }
19191932
19201933 /**
@@ -2036,7 +2049,32 @@
20372050 $wgOut->setPageTitle( wfMsg( 'nocreatetitle' ) );
20382051 $wgOut->addWikiText( wfMsg( 'nocreatetext' ) );
20392052 }
2040 -
 2053+
 2054+ /**
 2055+ * If there are rows in the deletion log for this page, show them,
 2056+ * along with a nice little note for the user
 2057+ *
 2058+ * @param OutputPage $out
 2059+ */
 2060+ private function showDeletionLog( $out ) {
 2061+ $title = $this->mArticle->getTitle();
 2062+ $reader = new LogReader(
 2063+ new FauxRequest(
 2064+ array(
 2065+ 'page' => $title->getPrefixedText(),
 2066+ 'type' => 'delete',
 2067+ )
 2068+ )
 2069+ );
 2070+ if( $reader->hasRows() ) {
 2071+ $out->addHtml( '<div id="mw-recreate-deleted-warn">' );
 2072+ $out->addWikiText( wfMsg( 'recreate-deleted-warn' ) );
 2073+ $viewer = new LogViewer( $reader );
 2074+ $viewer->showList( $out );
 2075+ $out->addHtml( '</div>' );
 2076+ }
 2077+ }
 2078+
20412079 }
20422080
20432081 ?>

Status & tagging log