r26283 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r26282‎ | r26283 | r26284 >
Date:19:50, 1 October 2007
Author:brion
Status:old
Tags:
Comment:
Revert r26281 for the moment. Big patch, changes several existing practices. Will want some public testing and more review before taking it to trunk.
Modified paths:
  • /trunk/phase3/includes/Article.php (modified) (history)
  • /trunk/phase3/includes/ChangesList.php (modified) (history)
  • /trunk/phase3/includes/DefaultSettings.php (modified) (history)
  • /trunk/phase3/includes/DifferenceEngine.php (modified) (history)
  • /trunk/phase3/includes/EditPage.php (modified) (history)
  • /trunk/phase3/includes/FileDeleteForm.php (modified) (history)
  • /trunk/phase3/includes/ImagePage.php (modified) (history)
  • /trunk/phase3/includes/Linker.php (modified) (history)
  • /trunk/phase3/includes/LogPage.php (modified) (history)
  • /trunk/phase3/includes/PageHistory.php (modified) (history)
  • /trunk/phase3/includes/RecentChange.php (modified) (history)
  • /trunk/phase3/includes/Revision.php (modified) (history)
  • /trunk/phase3/includes/Setup.php (modified) (history)
  • /trunk/phase3/includes/SpecialBlockip.php (modified) (history)
  • /trunk/phase3/includes/SpecialContributions.php (modified) (history)
  • /trunk/phase3/includes/SpecialIpblocklist.php (modified) (history)
  • /trunk/phase3/includes/SpecialLog.php (modified) (history)
  • /trunk/phase3/includes/SpecialMergeHistory.php (deleted) (history)
  • /trunk/phase3/includes/SpecialPage.php (modified) (history)
  • /trunk/phase3/includes/SpecialRecentchanges.php (modified) (history)
  • /trunk/phase3/includes/SpecialRevisiondelete.php (modified) (history)
  • /trunk/phase3/includes/SpecialSpecialpages.php (modified) (history)
  • /trunk/phase3/includes/SpecialUndelete.php (modified) (history)
  • /trunk/phase3/includes/SpecialWatchlist.php (modified) (history)
  • /trunk/phase3/includes/Title.php (modified) (history)
  • /trunk/phase3/includes/filerepo/ArchivedFile.php (modified) (history)
  • /trunk/phase3/includes/filerepo/FSRepo.php (modified) (history)
  • /trunk/phase3/includes/filerepo/File.php (modified) (history)
  • /trunk/phase3/includes/filerepo/FileRepo.php (modified) (history)
  • /trunk/phase3/includes/filerepo/LocalFile.php (modified) (history)
  • /trunk/phase3/includes/filerepo/OldLocalFile.php (modified) (history)
  • /trunk/phase3/languages/messages/MessagesEn.php (modified) (history)
  • /trunk/phase3/maintenance/rebuildrecentchanges.inc (modified) (history)
  • /trunk/phase3/maintenance/rebuildrecentchanges.php (modified) (history)

Diff [purge]

Index: trunk/phase3/languages/messages/MessagesEn.php
@@ -782,8 +782,6 @@
783783 'formerror' => 'Error: could not submit form',
784784 'badarticleerror' => 'This action cannot be performed on this page.',
785785 'cannotdelete' => 'Could not delete the page or file specified. (It may have already been deleted by someone else.)',
786 -'cannotdelete-merge' => 'Pages cannot be deleted if a different page already has archived revisions under the same title. This can
787 -happen if you move a page over another one and then delete it.',
788786 'badtitle' => 'Bad title',
789787 '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.',
790788 'perfdisabled' => 'Sorry! This feature has been temporarily disabled because it slows the database down to the point that no one can use the wiki.',
@@ -1148,11 +1146,10 @@
11491147 </div>',
11501148 'rev-delundel' => 'show/hide',
11511149 'revisiondelete' => 'Delete/undelete revisions',
1152 -'revdelete-nooldid-title' => 'Invalid target revision',
1153 -'revdelete-nooldid-text' => 'You have either not specified a target revision(s) to perform this
1154 -function, the specified revision does not exist, or you are attempting to hide the current revision.',
1155 -'revdelete-selected' => "{{PLURAL:$2|Selected revision|Selected revisions}} of [[:$1]]:",
1156 -'logdelete-selected' => "{{PLURAL:$1|Selected log event|Selected log events}}:",
 1150+'revdelete-nooldid-title' => 'No target revision',
 1151+'revdelete-nooldid-text' => 'You have not specified target revision or revisions to perform this function on.',
 1152+'revdelete-selected' => "{{PLURAL:$2|Selected revision|Selected revisions}} of '''$1:'''",
 1153+'logdelete-selected' => "{{PLURAL:$2|Selected log event|Selected log events}} for '''$1:'''",
11571154 'revdelete-text' => 'Deleted revisions and events will still appear in the page history and logs,
11581155 but parts of their content will be inaccessible to the public.
11591156
@@ -1163,7 +1160,7 @@
11641161 'revdelete-hide-name' => 'Hide action and target',
11651162 'revdelete-hide-comment' => 'Hide edit comment',
11661163 'revdelete-hide-user' => "Hide editor's username/IP",
1167 -'revdelete-hide-restricted' => 'Apply these restrictions to Sysops and lock this interface',
 1164+'revdelete-hide-restricted' => 'Apply these restrictions to sysops as well as others',
11681165 'revdelete-suppress' => 'Suppress data from sysops as well as others',
11691166 'revdelete-hide-image' => 'Hide file content',
11701167 'revdelete-unsuppress' => 'Remove restrictions on restored revisions',
@@ -1172,44 +1169,15 @@
11731170 'revdelete-logentry' => 'changed revision visibility of [[$1]]',
11741171 'logdelete-logentry' => 'changed event visibility of [[$1]]',
11751172 'revdelete-logaction' => '$1 {{PLURAL:$1|revision|revisions}} set to mode $2',
1176 -'logdelete-logaction' => '$1 {{PLURAL:$1|event|events}} set to mode $2',
1177 -'revdelete-success' => "'''Revision visibility successfully set.'''",
1178 -'logdelete-success' => "'''Log visibility successfully set.'''",
1179 -'revdel-restore' => 'Change visiblity',
 1173+'logdelete-logaction' => '$1 {{PLURAL:$1|event|events}} to [[$3]] set to mode $2',
 1174+'revdelete-success' => 'Revision visibility successfully set.',
 1175+'logdelete-success' => 'Event visibility successfully set.',
11801176
11811177 # Oversight log
1182 -'oversightlog' => 'Suppression log',
1183 -'overlogpagetext' => 'Below is a list of the most recent deletions and blocks involving items
1184 -hidden from Sysops. Automatically blocked IP addresses are not listed. See the [[Special:Ipblocklist|IP block list]]
1185 -for the list of currently operational bans and blocks.
 1178+'oversightlog' => 'Oversight log',
 1179+'overlogpagetext' => 'Below is a list of the most recent deletions and blocks involving content
 1180+hidden from Sysops. See the [[Special:Ipblocklist|IP block list]] for the list of currently operational bans and blocks.',
11861181
1187 -Blocked users listed here can cannot edit their talk pages and thus can only communicate via email. Their accounts
1188 -will remain hidden only as long as they are blocked.',
1189 -
1190 -# History merging
1191 -'mergehistory' => 'Merge page histories',
1192 -'mergehistory-header' => 'This page lets you merge revisions of the history of one source page into a newer page.
1193 -Please make sure that this change will maintain historical page continuity.
1194 -
1195 -At least the current revision of the source page must be left.',
1196 -'mergehistory-box' => 'Merge revisions of two pages:',
1197 -'mergehistory-from' => 'Source page:',
1198 -'mergehistory-into' => 'Destination page:',
1199 -'mergehistory-list' => 'Mergeable edit history',
1200 -'mergehistory-merge' => 'The following revisions of [[:$1|$1]] can be merged into [[:$2|$2]]. Use the radio
1201 -button column to merge in only the revisions created at or before the specified time. Note that you will have to
1202 -reselect any options if you use the navigation links.',
1203 -'mergehistory-go' => 'Show mergeable edits',
1204 -'mergehistory-submit' => 'Merge revisions',
1205 -'mergehistory-empty' => 'No revisions can be merged',
1206 -'mergehistory-success' => '$3 revisions of [[:$1]] successfully merged into [[:$2]].',
1207 -'mergehistory-fail' => 'Unable to perform history merge, please recheck the page and time parameters.',
1208 -
1209 -'mergelog' => 'Merge log',
1210 -'pagemerge-logentry' => 'merged $1 into $2 (revisions up to $3)',
1211 -'revertmerge' => 'Unmerge',
1212 -'mergelogpagetext' => 'Below is a list of the most recent merges of one page history into another.',
1213 -
12141182 # Diffs
12151183 'history-title' => 'Revision history of "$1"',
12161184 'difference' => '(Difference between revisions)',
@@ -1354,11 +1322,6 @@
13551323 'grouppage-sysop' => '{{ns:project}}:Administrators',
13561324 'grouppage-bureaucrat' => '{{ns:project}}:Bureaucrats',
13571325
1358 -'oversight' => 'Oversight',
1359 -'group-oversight' => 'Oversights',
1360 -'group-oversight-member' => 'Oversight',
1361 -'grouppage-oversight' => '{{ns:project}}:Oversight',
1362 -
13631326 # User rights log
13641327 'rightslog' => 'User rights log',
13651328 'rightslogtext' => 'This is a log of changes to user rights.',
@@ -1702,7 +1665,6 @@
17031666 'specialpages-summary' => '', # only translate this message to other languages if you have to change it
17041667 'spheading' => 'Special pages for all users',
17051668 'restrictedpheading' => 'Restricted special pages',
1706 -'restrictedlheading' => 'Restricted logs',
17071669 'rclsub' => '(to pages linked from "$1")',
17081670 'newpages' => 'New pages',
17091671 'newpages-summary' => '', # only translate this message to other languages if you have to change it
@@ -1741,10 +1703,10 @@
17421704 'specialloguserlabel' => 'User:',
17431705 'speciallogtitlelabel' => 'Title:',
17441706 'log' => 'Logs',
1745 -'all-logs-page' => 'All public logs',
 1707+'all-logs-page' => 'All logs',
17461708 'log-search-legend' => 'Search for logs',
17471709 'log-search-submit' => 'Go',
1748 -'alllogstext' => 'Combined display of all available public logs of {{SITENAME}}.
 1710+'alllogstext' => 'Combined display of all available logs of {{SITENAME}}.
17491711 You can narrow down the view by selecting a log type, the user name, or the affected page.',
17501712 'logempty' => 'No matching items in log.',
17511713 'log-title-wildcard' => 'Search titles starting with this text',
@@ -1891,7 +1853,6 @@
18921854 'deletedtext' => '"$1" has been deleted.
18931855 See $2 for a record of recent deletions.',
18941856 'deletedarticle' => 'deleted "[[$1]]"',
1895 -'suppressedarticle' => 'suppressed "[[$1]]"',
18961857 'dellogpage' => 'Deletion log',
18971858 'dellogpagetext' => 'Below is a list of the most recent deletions.',
18981859 'deletionlog' => 'deletion log',
@@ -1912,7 +1873,6 @@
19131874 'sessionfailure' => 'There seems to be a problem with your login session;
19141875 this action has been canceled as a precaution against session hijacking.
19151876 Please hit "back" and reload the page you came from, then try again.',
1916 -
19171877 'protectlogpage' => 'Protection log',
19181878 '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.',
19191879 'protectedarticle' => 'protected "[[$1]]"',
@@ -1920,7 +1880,6 @@
19211881 'unprotectedarticle' => 'unprotected "[[$1]]"',
19221882 'protectsub' => '(Setting protection level for "$1")',
19231883 'confirmprotect' => 'Confirm protection',
1924 -'protect-fileonly' => 'Apply edit restrictions to file uploads only',
19251884 'protectcomment' => 'Comment:',
19261885 'protectexpiry' => 'Expires:',
19271886 'protect_expiry_invalid' => 'Expiry time is invalid.',
@@ -1951,7 +1910,6 @@
19521911 # Restrictions (nouns)
19531912 'restriction-edit' => 'Edit',
19541913 'restriction-move' => 'Move',
1955 -'restriction-upload' => 'Upload',
19561914
19571915 # Restriction levels
19581916 'restriction-level-sysop' => 'full protected',
@@ -1960,29 +1918,25 @@
19611919
19621920 # Undelete
19631921 'undelete' => 'View deleted pages',
1964 -'undeleterevs' => 'Deleted revisions',
19651922 'undeletepage' => 'View and restore deleted pages',
19661923 'viewdeletedpage' => 'View deleted pages',
1967 -'undeletepagetitle' => '\'\'\'The following consists of deleted revisions of [[:$1]]\'\'\'.',
19681924 'undeletepagetext' => 'The following pages have been deleted but are still in the archive and
19691925 can be restored. The archive may be periodically cleaned out.',
1970 -'undeleteextrahelp' => "To restore the entire page, leave all radios deselected and click '''''Restore'''''.
1971 -To perform a selective restoration, check the desired restore point below and click '''''Restore'''''.
1972 -Clicking '''''Reset''''' will reset this form. Note that you will have to reselect any options if you
1973 -use the navigation links.",
 1926+'undeleteextrahelp' => "To restore the entire page, leave all checkboxes deselected and
 1927+click '''''Restore'''''. To perform a selective restoration, check the boxes corresponding to the
 1928+revisions to be restored, and click '''''Restore'''''. Clicking '''''Reset''''' will clear the
 1929+comment field and all checkboxes.",
19741930 'undeleterevisions' => '$1 {{PLURAL:$1|revision|revisions}} archived',
19751931 'undeletehistory' => 'If you restore the page, all revisions will be restored to the history.
19761932 If a new page with the same name has been created since the deletion, the restored
19771933 revisions will appear in the prior history, and the current revision of the live page
1978 -will not be automatically replaced.',
1979 -'undeleterevdel' => 'Undeletion will not be performed if either it would result in the top page/image revision
1980 -being restricted. Histories of different pages cannot be merged unless the live page is a redirect with no edit history.',
 1934+will not be automatically replaced. Also note that restrictions on file revisions are lost upon restoration',
 1935+'undeleterevdel' => "Undeletion will not be performed if it will result in the top page revision being
 1936+partially deleted. In such cases, you must uncheck or unhide the newest deleted revisions. Revisions of files
 1937+that you don't have permission to view will not be restored.",
19811938 'undeletehistorynoadmin' => 'This article has been deleted. The reason for deletion is
19821939 shown in the summary below, along with details of the users who had edited this page
19831940 before deletion. The actual text of these deleted revisions is only available to administrators.',
1984 -'restorepoint' => 'Use the radio button column to restore only revisions from the specified time onwards.',
1985 -'restorenone' => '(select this button to restore none of these revisions)',
1986 -
19871941 'undelete-revision' => 'Deleted revision of $1 (as of $2) by $3:',
19881942 'undeleterevision-missing' => 'Invalid or missing revision. You may have a bad link, or the
19891943 revision may have been restored or removed from the archive.',
Index: trunk/phase3/includes/SpecialMergeHistory.php
@@ -1,418 +0,0 @@
2 -<?php
3 -
4 -/**
5 - * Special page allowing users with the appropriate permissions to
6 - * merge article histories, with some restrictions
7 - *
8 - * @addtogroup SpecialPage
9 - */
10 -
11 -/**
12 - * Constructor
13 - */
14 -function wfSpecialMergehistory( $par ) {
15 - global $wgRequest;
16 -
17 - $form = new MergehistoryForm( $wgRequest, $par );
18 - $form->execute();
19 -}
20 -
21 -/**
22 - * The HTML form for Special:MergeHistory, which allows users with the appropriate
23 - * permissions to view and restore deleted content.
24 - * @addtogroup SpecialPage
25 - */
26 -class MergehistoryForm {
27 - var $mAction, $mTarget, $mDest, $mTimestamp, $mTargetID, $mDestID, $mComment;
28 - var $mTargetObj, $mDestObj;
29 -
30 - function MergehistoryForm( $request, $par = "" ) {
31 - global $wgUser;
32 -
33 - $this->mAction = $request->getVal( 'action' );
34 - $this->mTarget = $request->getVal( 'target' );
35 - $this->mDest = $request->getVal( 'dest' );
36 -
37 - $this->mTargetID = intval( $request->getVal( 'targetID' ) );
38 - $this->mDestID = intval( $request->getVal( 'destID' ) );
39 - $this->mTimestamp = $request->getVal( 'mergepoint' );
40 - $this->mComment = $request->getText( 'wpComment' );
41 -
42 - $this->mMerge = $request->wasPosted() && $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) );
43 - // target page
44 - if( $this->mTarget !== "" ) {
45 - $this->mTargetObj = Title::newFromURL( $this->mTarget );
46 - } else {
47 - $this->mTargetObj = NULL;
48 - }
49 - # Destination
50 - if( $this->mDest !== "" ) {
51 - $this->mDestObj = Title::newFromURL( $this->mDest );
52 - } else {
53 - $this->mDestObj = NULL;
54 - }
55 -
56 - $this->preCacheMessages();
57 - }
58 -
59 - /**
60 - * As we use the same small set of messages in various methods and that
61 - * they are called often, we call them once and save them in $this->message
62 - */
63 - function preCacheMessages() {
64 - // Precache various messages
65 - if( !isset( $this->message ) ) {
66 - $this->message['last'] = wfMsgExt( 'last', array( 'escape') );
67 - }
68 - }
69 -
70 - function execute() {
71 - global $wgOut, $wgUser;
72 -
73 - $wgOut->setPagetitle( wfMsgHtml( "mergehistory" ) );
74 -
75 - if( $this->mTargetID && $this->mDestID && $this->mAction=="submit" && $this->mMerge ) {
76 - return $this->merge();
77 - }
78 -
79 - if( is_object($this->mTargetObj) && is_object($this->mDestObj) ) {
80 - return $this->showHistory();
81 - }
82 -
83 - return $this->showMergeForm();
84 - }
85 -
86 - function showMergeForm() {
87 - global $wgOut, $wgScript;
88 -
89 - $wgOut->addWikiText( wfMsg( 'mergehistory-header' ) );
90 -
91 - $wgOut->addHtml(
92 - Xml::openElement( 'form', array(
93 - 'method' => 'get',
94 - 'action' => $wgScript ) ) .
95 - '<fieldset>' .
96 - Xml::element( 'legend', array(),
97 - wfMsg( 'mergehistory-box' ) ) .
98 - Xml::hidden( 'title',
99 - SpecialPage::getTitleFor( 'Mergehistory' )->getPrefixedDbKey() ) .
100 - Xml::openElement( 'table' ) .
101 - "<tr>
102 - <td>".Xml::Label( wfMsg( 'mergehistory-from' ), 'target' )."</td>
103 - <td>".Xml::input( 'target', 30, $this->mTarget, array('id'=>'target') )."</td>
104 - </tr><tr>
105 - <td>".Xml::Label( wfMsg( 'mergehistory-into' ), 'dest' )."</td>
106 - <td>".Xml::input( 'dest', 30, $this->mDest, array('id'=>'dest') )."</td>
107 - </tr><tr><td>" .
108 - Xml::submitButton( wfMsg( 'mergehistory-go' ) ) .
109 - "</td></tr>" .
110 - Xml::closeElement( 'table' ) .
111 - '</fieldset>' .
112 - '</form>' );
113 - }
114 -
115 - private function showHistory() {
116 - global $wgLang, $wgContLang, $wgUser, $wgOut;
117 -
118 - $this->sk = $wgUser->getSkin();
119 -
120 - $wgOut->setPagetitle( wfMsg( "mergehistory" ) );
121 -
122 - $this->showMergeForm();
123 -
124 - # List all stored revisions
125 - $revisions = new MergeHistoryPager( $this, array(), $this->mTargetObj, $this->mDestObj );
126 - $haveRevisions = $revisions && $revisions->getNumRows() > 0;
127 -
128 - $titleObj = SpecialPage::getTitleFor( "Mergehistory" );
129 - $action = $titleObj->getLocalURL( "action=submit" );
130 - # Start the form here
131 - $top = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $action, 'id' => 'merge' ) );
132 - $wgOut->addHtml( $top );
133 -
134 - if( $haveRevisions ) {
135 - # Format the user-visible controls (comment field, submission button)
136 - # in a nice little table
137 - $align = $wgContLang->isRtl() ? 'left' : 'right';
138 - $table =
139 - Xml::openElement( 'fieldset' ) .
140 - Xml::openElement( 'table' ) .
141 - "<tr>
142 - <td colspan='2'>" .
143 - wfMsgExt( 'mergehistory-merge', array('parseinline'),
144 - $this->mTargetObj->getPrefixedText(), $this->mDestObj->getPrefixedText() ) .
145 - "</td>
146 - </tr>
147 - <tr>
148 - <td align='$align'>" .
149 - Xml::label( wfMsg( 'undeletecomment' ), 'wpComment' ) .
150 - "</td>
151 - <td>" .
152 - Xml::input( 'wpComment', 50, $this->mComment ) .
153 - "</td>
154 - </tr>
155 - <tr>
156 - <td>&nbsp;</td>
157 - <td>" .
158 - Xml::submitButton( wfMsg( 'mergehistory-submit' ), array( 'name' => 'merge', 'id' => 'mw-merge-submit' ) ) .
159 - "</td>
160 - </tr>" .
161 - Xml::closeElement( 'table' ) .
162 - Xml::closeElement( 'fieldset' );
163 -
164 - $wgOut->addHtml( $table );
165 - }
166 -
167 - $wgOut->addHTML( "<h2 id=\"mergehistory\">" . wfMsgHtml( "mergehistory-list" ) . "</h2>\n" );
168 -
169 - if( $haveRevisions ) {
170 - $wgOut->addHTML( $revisions->getNavigationBar() );
171 - $wgOut->addHTML( "<ul>" );
172 - $wgOut->addHTML( $revisions->getBody() );
173 - $wgOut->addHTML( "</ul>" );
174 - $wgOut->addHTML( $revisions->getNavigationBar() );
175 - } else {
176 - $wgOut->addWikiText( wfMsg( "mergehistory-empty" ) );
177 - }
178 -
179 - # Show relevant lines from the deletion log:
180 - $wgOut->addHTML( "<h2>" . htmlspecialchars( LogPage::logName( 'merge' ) ) . "</h2>\n" );
181 - $logViewer = new LogViewer(
182 - new LogReader(
183 - new FauxRequest(
184 - array( 'page' => $this->mTargetObj->getPrefixedText(),
185 - 'type' => 'merge' ) ) ) );
186 - $logViewer->showList( $wgOut );
187 -
188 - # Slip in the hidden controls here
189 - # When we submit, go by page ID to avoid some nasty but unlikely collisions.
190 - # Such would happen if a page was renamed after the form loaded, but before submit
191 - $misc = Xml::hidden( 'targetID', $this->mTargetObj->getArticleID() );
192 - $misc .= Xml::hidden( 'destID', $this->mDestObj->getArticleID() );
193 - $misc .= Xml::hidden( 'target', $this->mTarget );
194 - $misc .= Xml::hidden( 'dest', $this->mDest );
195 - $misc .= Xml::hidden( 'wpEditToken', $wgUser->editToken() );
196 - $misc .= Xml::closeElement( 'form' );
197 - $wgOut->addHtml( $misc );
198 -
199 - return true;
200 - }
201 -
202 - function formatRevisionRow( $row ) {
203 - global $wgUser, $wgLang;
204 -
205 - $rev = new Revision( $row );
206 -
207 - $stxt = '';
208 - $last = $this->message['last'];
209 -
210 - $ts = wfTimestamp( TS_MW, $row->rev_timestamp );
211 - $checkBox = wfRadio( "mergepoint", $ts, false );
212 -
213 - $pageLink = $this->sk->makeKnownLinkObj( $rev->getTitle(), $wgLang->timeanddate( $ts ), 'oldid=' . $rev->getID() );
214 - if( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
215 - $pageLink = '<span class="history-deleted">' . $pageLink . '</span>';
216 - }
217 -
218 - # Last link
219 - if( !$rev->userCan( Revision::DELETED_TEXT ) )
220 - $last = $this->message['last'];
221 - else if( isset($this->prevId[$row->rev_id]) )
222 - $last = $this->sk->makeKnownLinkObj( $rev->getTitle(), $this->message['last'],
223 - "&diff=" . $row->rev_id . "&oldid=" . $this->prevId[$row->rev_id] );
224 -
225 - $userLink = $this->sk->userLink( $rev->getUser(), $rev->getUserText() )
226 - . $this->sk->userToolLinks( $rev->getUser(), $rev->getUserText() );
227 -
228 - if(!is_null($size = $row->rev_len)) {
229 - if($size == 0)
230 - $stxt = wfMsgHtml('historyempty');
231 - else
232 - $stxt = wfMsgHtml('historysize', $wgLang->formatNum( $size ) );
233 - }
234 - $comment = $this->sk->revComment( $rev );
235 -
236 - return "<li>$checkBox ($last) $pageLink . . $userLink $stxt $comment</li>";
237 - }
238 -
239 - /**
240 - * Fetch revision text link if it's available to all users
241 - * @return string
242 - */
243 - function getPageLink( $row, $titleObj, $ts, $target ) {
244 - global $wgLang;
245 -
246 - if( !$this->userCan($row, Revision::DELETED_TEXT) ) {
247 - return '<span class="history-deleted">' . $wgLang->timeanddate( $ts, true ) . '</span>';
248 - } else {
249 - $link = $this->sk->makeKnownLinkObj( $titleObj, $wgLang->timeanddate( $ts, true ), "target=$target&timestamp=$ts" );
250 - if( $this->isDeleted($row, Revision::DELETED_TEXT) )
251 - $link = '<span class="history-deleted">' . $link . '</span>';
252 - return $link;
253 - }
254 - }
255 -
256 - /**
257 - * Fetch revision's user id if it's available to this user
258 - * @return string
259 - */
260 - function getUser( $row ) {
261 - if( !$this->userCan($row, Revision::DELETED_USER) ) {
262 - return '<span class="history-deleted">' . wfMsgHtml( 'rev-deleted-user' ) . '</span>';
263 - } else {
264 - $link = $this->sk->userLink( $row->rev_user, $row->rev_user_text ) . $this->sk->userToolLinks( $row->rev_user, $row->rev_user_text );
265 - if( $this->isDeleted($row, Revision::DELETED_USER) )
266 - $link = '<span class="history-deleted">' . $link . '</span>';
267 - return $link;
268 - }
269 - }
270 -
271 - /**
272 - * Fetch revision comment if it's available to this user
273 - * @return string
274 - */
275 - function getComment( $row ) {
276 - if( !$this->userCan($row, Revision::DELETED_COMMENT) ) {
277 - return '<span class="history-deleted"><span class="comment">' . wfMsgHtml( 'rev-deleted-comment' ) . '</span></span>';
278 - } else {
279 - $link = $this->sk->commentBlock( $row->rev_comment );
280 - if( $this->isDeleted($row, Revision::DELETED_COMMENT) )
281 - $link = '<span class="history-deleted">' . $link . '</span>';
282 - return $link;
283 - }
284 - }
285 -
286 - function merge() {
287 - global $wgOut, $wgUser;
288 - # Get the titles directly from the IDs, in case the target page params
289 - # were spoofed. The queries are done based on the IDs, so it's best to
290 - # keep it consistent...
291 - $targetTitle = Title::newFromID( $this->mTargetID );
292 - $destTitle = Title::newFromID( $this->mDestID );
293 - if( is_null($targetTitle) || is_null($destTitle) )
294 - return false; // validate these
295 - # Verify that this timestamp is valid
296 - # Must be older than the destination page
297 - $dbw = wfGetDB( DB_MASTER );
298 - $maxtimestamp = $dbw->selectField( 'revision', 'MIN(rev_timestamp)',
299 - array('rev_page' => $this->mDestID ),
300 - __METHOD__ );
301 - # Destination page must exist with revisions
302 - if( !$maxtimestamp ) {
303 - $wgOut->addHtml( wfMsg('mergehistory-fail') );
304 - return false;
305 - }
306 - # Leave the latest version no matter what
307 - $lasttime = $dbw->selectField( array('page','revision'),
308 - 'rev_timestamp',
309 - array('page_id' => $this->mTargetID, 'page_latest = rev_id' ),
310 - __METHOD__ );
311 - # Take the most restrictive of the twain
312 - $maxtimestamp = ($lasttime < $maxtimestamp) ? $lasttime : $maxtimestamp;
313 - if( $this->mTimestamp && $this->mTimestamp >= $maxtimestamp ) {
314 - $wgOut->addHtml( wfMsg('mergehistory-fail') );
315 - return false;
316 - }
317 - # Update the revisions
318 - if( $this->mTimestamp )
319 - $timewhere = "rev_timestamp <= {$this->mTimestamp}";
320 - else
321 - $timewhere = '1 = 1';
322 -
323 - $dbw->update( 'revision',
324 - array( 'rev_page' => $this->mDestID ),
325 - array( 'rev_page' => $this->mTargetID,
326 - "rev_timestamp < {$maxtimestamp}",
327 - $timewhere ),
328 - __METHOD__ );
329 - # Check if this did anything
330 - $count = $dbw->affectedRows();
331 - if( !$count ) {
332 - $wgOut->addHtml( wfMsg('mergehistory-fail') );
333 - return false;
334 - }
335 - # Update our logs
336 - $log = new LogPage( 'merge' );
337 - $log->addEntry( 'merge', $targetTitle, $this->mComment,
338 - array($destTitle->getPrefixedText(),$this->mTimestamp) );
339 -
340 - $wgOut->addHtml( wfMsgExt( 'mergehistory-success', array('parseinline'),
341 - $targetTitle->getPrefixedText(), $destTitle->getPrefixedText(), $count ) );
342 -
343 - wfRunHooks( 'ArticleMergeComplete', array( $targetTitle, $destTitle ) );
344 -
345 - return true;
346 - }
347 -}
348 -
349 -class MergeHistoryPager extends ReverseChronologicalPager {
350 - public $mForm, $mConds;
351 -
352 - function __construct( $form, $conds = array(), $title, $title2 ) {
353 - $this->mForm = $form;
354 - $this->mConds = $conds;
355 - $this->title = $title;
356 - $this->articleID = $title->getArticleID();
357 -
358 - $dbw = wfGetDB( DB_SLAVE );
359 - $maxtimestamp = $dbw->selectField('revision', 'MIN(rev_timestamp)',
360 - array('rev_page' => $title2->getArticleID() ),
361 - __METHOD__ );
362 - $maxtimestamp = $maxtimestamp ? $maxtimestamp : 0;
363 - $this->maxTimestamp = $maxtimestamp;
364 -
365 - parent::__construct();
366 - }
367 -
368 - function getStartBody() {
369 - wfProfileIn( __METHOD__ );
370 - # Do a link batch query
371 - $this->mResult->seek( 0 );
372 - $batch = new LinkBatch();
373 - # Give some pointers to make (last) links
374 - $this->mForm->prevId = array();
375 - while( $row = $this->mResult->fetchObject() ) {
376 - $batch->addObj( Title::makeTitleSafe( NS_USER, $row->rev_user_text ) );
377 - $batch->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->rev_user_text ) );
378 -
379 - $rev_id = isset($rev_id) ? $rev_id : $row->rev_id;
380 - if( $rev_id > $row->rev_id )
381 - $this->mForm->prevId[$rev_id] = $row->rev_id;
382 - else if( $rev_id < $row->rev_id )
383 - $this->mForm->prevId[$row->rev_id] = $rev_id;
384 -
385 - $rev_id = $row->rev_id;
386 - }
387 -
388 - $batch->execute();
389 - $this->mResult->seek( 0 );
390 -
391 - wfProfileOut( __METHOD__ );
392 - return '';
393 - }
394 -
395 - function formatRow( $row ) {
396 - $block = new Block;
397 - return $this->mForm->formatRevisionRow( $row );
398 - }
399 -
400 - function getQueryInfo() {
401 - $conds = $this->mConds;
402 - $conds['rev_page'] = $this->articleID;
403 - $conds[] = "rev_timestamp < {$this->maxTimestamp}";
404 - # Skip the latest one, as that could cause problems
405 - if( $page = $this->title->getLatestRevID() )
406 - $conds[] = "rev_id != {$page}";
407 -
408 - return array(
409 - 'tables' => array('revision'),
410 - 'fields' => array( 'rev_minor_edit', 'rev_timestamp', 'rev_user', 'rev_user_text', 'rev_comment',
411 - 'rev_id', 'rev_page', 'rev_text_id', 'rev_len', 'rev_deleted' ),
412 - 'conds' => $conds
413 - );
414 - }
415 -
416 - function getIndexField() {
417 - return 'rev_timestamp';
418 - }
419 -}
Index: trunk/phase3/includes/RecentChange.php
@@ -25,11 +25,6 @@
2626 * rc_patrolled boolean whether or not someone has marked this edit as patrolled
2727 * rc_old_len integer byte length of the text before the edit
2828 * rc_new_len the same after the edit
29 - * rc_deleted partial deletion
30 - * rc_logid the log_id value for this log entry (or zero)
31 - * rc_log_type the log type (or null)
32 - * rc_log_action the log action (or null)
33 - * rc_params log params
3429 *
3530 * mExtra:
3631 * prefixedDBkey prefixed db key, used by external app via msg queue
@@ -300,12 +295,7 @@
301296 'rc_patrolled' => 0,
302297 'rc_new' => 0, # obsolete
303298 'rc_old_len' => $oldSize,
304 - 'rc_new_len' => $newSize,
305 - 'rc_deleted' => 0,
306 - 'rc_logid' => 0,
307 - 'rc_log_type' => null,
308 - 'rc_log_action' => '',
309 - 'rc_params' => ''
 299+ 'rc_new_len' => $newSize
310300 );
311301
312302 $rc->mExtra = array(
@@ -326,9 +316,11 @@
327317 public static function notifyNew( $timestamp, &$title, $minor, &$user, $comment, $bot = 'default',
328318 $ip='', $size = 0, $newId = 0 )
329319 {
330 - if( !$ip ) {
 320+ if ( !$ip ) {
331321 $ip = wfGetIP();
332 - if( !$ip ) $ip = '';
 322+ if ( !$ip ) {
 323+ $ip = '';
 324+ }
333325 }
334326 if ( $bot === 'default' ) {
335327 $bot = $user->isAllowed( 'bot' );
@@ -353,14 +345,9 @@
354346 'rc_moved_to_title' => '',
355347 'rc_ip' => $ip,
356348 'rc_patrolled' => 0,
357 - 'rc_new' => 1, # obsolete
 349+ 'rc_new' => 1, # obsolete
358350 'rc_old_len' => 0,
359 - 'rc_new_len' => $size,
360 - 'rc_deleted' => 0,
361 - 'rc_logid' => 0,
362 - 'rc_log_type' => null,
363 - 'rc_log_action' => '',
364 - 'rc_params' => ''
 351+ 'rc_new_len' => $size
365352 );
366353
367354 $rc->mExtra = array(
@@ -376,9 +363,11 @@
377364 # Makes an entry in the database corresponding to a rename
378365 public static function notifyMove( $timestamp, &$oldTitle, &$newTitle, &$user, $comment, $ip='', $overRedir = false )
379366 {
380 - if( !$ip ) {
 367+ if ( !$ip ) {
381368 $ip = wfGetIP();
382 - if( !$ip ) $ip = '';
 369+ if ( !$ip ) {
 370+ $ip = '';
 371+ }
383372 }
384373
385374 $rc = new RecentChange;
@@ -403,11 +392,6 @@
404393 'rc_patrolled' => 1,
405394 'rc_old_len' => NULL,
406395 'rc_new_len' => NULL,
407 - 'rc_deleted' => 0,
408 - 'rc_logid' => 0, # notifyMove not used anymore
409 - 'rc_log_type' => null,
410 - 'rc_log_action' => '',
411 - 'rc_params' => ''
412396 );
413397
414398 $rc->mExtra = array(
@@ -426,27 +410,30 @@
427411 RecentChange::notifyMove( $timestamp, $oldTitle, $newTitle, $user, $comment, $ip, true );
428412 }
429413
430 - # A log entry is different to an edit in that previous revisions are not kept
 414+ # A log entry is different to an edit in that previous revisions are
 415+ # not kept
431416 public static function notifyLog( $timestamp, &$title, &$user, $comment, $ip='',
432 - $type, $action, $target, $logComment, $params, $newId=0 )
 417+ $type, $action, $target, $logComment, $params )
433418 {
434 - if( !$ip ) {
 419+ if ( !$ip ) {
435420 $ip = wfGetIP();
436 - if( !$ip ) $ip = '';
 421+ if ( !$ip ) {
 422+ $ip = '';
 423+ }
437424 }
438425
439426 $rc = new RecentChange;
440427 $rc->mAttribs = array(
441428 'rc_timestamp' => $timestamp,
442429 'rc_cur_time' => $timestamp,
443 - 'rc_namespace' => $target->getNamespace(),
444 - 'rc_title' => $target->getDBkey(),
 430+ 'rc_namespace' => $title->getNamespace(),
 431+ 'rc_title' => $title->getDBkey(),
445432 'rc_type' => RC_LOG,
446433 'rc_minor' => 0,
447 - 'rc_cur_id' => $target->getArticleID(),
 434+ 'rc_cur_id' => $title->getArticleID(),
448435 'rc_user' => $user->getID(),
449436 'rc_user_text' => $user->getName(),
450 - 'rc_comment' => $logComment,
 437+ 'rc_comment' => $comment,
451438 'rc_this_oldid' => 0,
452439 'rc_last_oldid' => 0,
453440 'rc_bot' => $user->isAllowed( 'bot' ) ? 1 : 0,
@@ -457,11 +444,6 @@
458445 'rc_new' => 0, # obsolete
459446 'rc_old_len' => NULL,
460447 'rc_new_len' => NULL,
461 - 'rc_deleted' => 0,
462 - 'rc_logid' => $newId,
463 - 'rc_log_type' => $type,
464 - 'rc_log_action' => $action,
465 - 'rc_params' => $params
466448 );
467449 $rc->mExtra = array(
468450 'prefixedDBkey' => $title->getPrefixedDBkey(),
@@ -508,11 +490,6 @@
509491 'rc_new' => $row->page_is_new, # obsolete
510492 'rc_old_len' => $row->rc_old_len,
511493 'rc_new_len' => $row->rc_new_len,
512 - 'rc_deleted' => $row->rc_deleted,
513 - 'rc_logid' => $row->rc_logid,
514 - 'rc_log_type' => $row->rc_log_type,
515 - 'rc_log_action' => $row->rc_log_action,
516 - 'rc_params' => $row->rc_params
517494 );
518495
519496 $this->mExtra = array();
Index: trunk/phase3/includes/PageHistory.php
@@ -37,21 +37,7 @@
3838 $this->mTitle =& $article->mTitle;
3939 $this->mNotificationTimestamp = NULL;
4040 $this->mSkin = $wgUser->getSkin();
41 - $this->preCacheMessages();
4241 }
43 -
44 - /**
45 - * As we use the same small set of messages in various methods and that
46 - * they are called often, we call them once and save them in $this->message
47 - */
48 - function preCacheMessages() {
49 - // Precache various messages
50 - if( !isset( $this->message ) ) {
51 - foreach( explode(' ', 'cur last rev-delundel' ) as $msg ) {
52 - $this->message[$msg] = wfMsgExt( $msg, array( 'escape') );
53 - }
54 - }
55 - }
5642
5743 /**
5844 * Print the history page for an article.
@@ -203,31 +189,35 @@
204190 $arbitrary = $this->diffButtons( $rev, $firstInList, $counter );
205191 $link = $this->revLink( $rev );
206192
 193+ $user = $this->mSkin->userLink( $rev->getUser(), $rev->getUserText() )
 194+ . $this->mSkin->userToolLinks( $rev->getUser(), $rev->getUserText() );
 195+
207196 $s .= "($curlink) ($lastlink) $arbitrary";
208197
209198 if( $wgUser->isAllowed( 'deleterevision' ) ) {
210199 $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
211200 if( $firstInList ) {
212 - // We don't currently handle well changing the top revision's settings
213 - $del = $this->message['rev-delundel'];
 201+ // We don't currently handle well changing the top revision's settings
 202+ $del = wfMsgHtml( 'rev-delundel' );
214203 } else if( !$rev->userCan( Revision::DELETED_RESTRICTED ) ) {
215204 // If revision was hidden from sysops
216 - $del = $this->message['rev-delundel'];
 205+ $del = wfMsgHtml( 'rev-delundel' );
217206 } else {
218207 $del = $this->mSkin->makeKnownLinkObj( $revdel,
219 - $this->message['rev-delundel'],
 208+ wfMsg( 'rev-delundel' ),
220209 'target=' . urlencode( $this->mTitle->getPrefixedDbkey() ) .
221210 '&oldid=' . urlencode( $rev->getId() ) );
222 - // Bolden oversighted content
223 - if( $rev->isDeleted( Revision::DELETED_RESTRICTED ) )
224 - $del = "<strong>$del</strong>";
225211 }
226 - $s .= " <tt>(<small>$del</small>)</tt> ";
 212+ $s .= " (<small>$del</small>) ";
227213 }
228214
229215 $s .= " $link";
230 - $s .= ' '.$this->mSkin->revUserTools( $rev, true);
231 -
 216+ #getUser is safe, but this avoids making the invalid untargeted contribs links
 217+ if( $row->rev_deleted & Revision::DELETED_USER ) {
 218+ $user = '<span class="history-deleted">' . wfMsg('rev-deleted-user') . '</span>';
 219+ }
 220+ $s .= " <span class='history-user'>$user</span>";
 221+
232222 if( $row->rev_minor_edit ) {
233223 $s .= ' ' . wfElement( 'span', array( 'class' => 'minor' ), wfMsg( 'minoreditletter') );
234224 }
@@ -253,7 +243,7 @@
254244 }
255245 #add blurb about text having been deleted
256246 if( $row->rev_deleted & Revision::DELETED_TEXT ) {
257 - $s .= ' <tt>' . wfMsgHtml( 'deletedrev' ) . '</tt>';
 247+ $s .= ' ' . wfMsgHtml( 'deletedrev' );
258248 }
259249
260250 $tools = array();
@@ -302,7 +292,7 @@
303293
304294 /** @todo document */
305295 function curLink( $rev, $latest ) {
306 - $cur = $this->message['cur'];
 296+ $cur = wfMsgExt( 'cur', array( 'escape') );
307297 if( $latest || !$rev->userCan( Revision::DELETED_TEXT ) ) {
308298 return $cur;
309299 } else {
@@ -315,7 +305,7 @@
316306
317307 /** @todo document */
318308 function lastLink( $rev, $next, $counter ) {
319 - $last = $this->message['last'];
 309+ $last = wfMsgExt( 'last', array( 'escape' ) );
320310 if ( is_null( $next ) ) {
321311 # Probably no next row
322312 return $last;
Index: trunk/phase3/includes/SpecialRecentchanges.php
@@ -408,7 +408,7 @@
409409 rcFormatDiff( $obj ),
410410 $title->getFullURL(),
411411 $obj->rc_timestamp,
412 - ($obj->rc_deleted & Revision::DELETED_USER) ? wfMsgHtml('rev-deleted-user') : $obj->rc_user_text,
 412+ $obj->rc_user_text,
413413 $talkpage->getFullURL()
414414 );
415415 $feed->outItem( $item );
@@ -617,18 +617,15 @@
618618 return rcFormatDiffRow( $titleObj,
619619 $row->rc_last_oldid, $row->rc_this_oldid,
620620 $timestamp,
621 - ($row->rc_deleted & Revision::DELETED_COMMENT) ? wfMsgHtml('rev-deleted-comment') : $row->rc_comment,
622 - ($row->rc_deleted & LogViewer::DELETED_ACTION) ? wfMsgHtml('rev-deleted-event') : $row->rc_actiontext );
 621+ $row->rc_comment );
623622 }
624623
625 -function rcFormatDiffRow( $title, $oldid, $newid, $timestamp, $comment, $actiontext='' ) {
 624+function rcFormatDiffRow( $title, $oldid, $newid, $timestamp, $comment ) {
626625 global $wgFeedDiffCutoff, $wgContLang, $wgUser;
627626 $fname = 'rcFormatDiff';
628627 wfProfileIn( $fname );
629628
630629 $skin = $wgUser->getSkin();
631 - # log enties
632 - if( $actiontext ) $comment = "$actiontext $comment";
633630 $completeText = '<p>' . $skin->formatComment( $comment ) . "</p>\n";
634631
635632 //NOTE: Check permissions for anonymous users, not current user.
Index: trunk/phase3/includes/SpecialPage.php
@@ -131,7 +131,7 @@
132132 'Log' => array( 'SpecialPage', 'Log' ),
133133 'Blockip' => array( 'SpecialPage', 'Blockip', 'block' ),
134134 'Undelete' => array( 'SpecialPage', 'Undelete', 'deletedhistory' ),
135 - 'Import' => array( 'SpecialPage', 'Import', 'import' ),
 135+ 'Import' => array( 'SpecialPage', "Import", 'import' ),
136136 'Lockdb' => array( 'SpecialPage', 'Lockdb', 'siteadmin' ),
137137 'Unlockdb' => array( 'SpecialPage', 'Unlockdb', 'siteadmin' ),
138138 'Userrights' => array( 'SpecialPage', 'Userrights', 'userrights' ),
@@ -147,7 +147,6 @@
148148 'Mytalk' => array( 'SpecialMytalk' ),
149149 'Mycontributions' => array( 'SpecialMycontributions' ),
150150 'Listadmins' => array( 'SpecialRedirectToSpecial', 'Listadmins', 'Listusers', 'sysop' ),
151 - 'MergeHistory' => array( 'SpecialPage', 'Mergehistory', 'mergehistory' ),
152151 );
153152
154153 static public $mAliases;
@@ -380,28 +379,6 @@
381380 }
382381 return $pages;
383382 }
384 -
385 - /**
386 - * Return categorised listable log pages which are available
387 - * for the current user, but not for everyone
388 - * @static
389 - */
390 - static function getRestrictedLogs() {
391 - global $wgUser, $wgLogRestrictions, $wgLogNames;
392 -
393 - $pages = array();
394 -
395 - if ( isset($wgLogRestrictions) ) {
396 - foreach ( $wgLogRestrictions as $type => $restriction ) {
397 - $page = SpecialPage::getTitleFor( 'Log', $type );
398 - if ( $restriction !='' && $restriction !='*' && $wgUser->isAllowed( $restriction ) ) {
399 - $name = wfMsgHtml( $wgLogNames[$type] );
400 - $pages[$name] = $page;
401 - }
402 - }
403 - }
404 - return $pages;
405 - }
406383
407384 /**
408385 * Execute a special page path.
Index: trunk/phase3/includes/Title.php
@@ -2445,38 +2445,6 @@
24462446 }
24472447
24482448 /**
2449 - * Checks if the deleted history of another page can be merged into the same title as $this
2450 - * - Selects for update, so don't call it unless you mean business
2451 - */
2452 - public function isValidRestoreOverTarget() {
2453 -
2454 - $fname = 'Title::isValidRestoreOverTarget';
2455 - $dbw = wfGetDB( DB_MASTER );
2456 -
2457 - # Is it a redirect?
2458 - $page_is_redirect = $dbw->selectField( 'page', 'page_is_redirect',
2459 - array( 'page_namespace' => $this->mNamespace, 'page_title' => $this->mDbkeyform ),
2460 - $fname, 'FOR UPDATE' );
2461 -
2462 - if ( !$page_is_redirect ) {
2463 - # Not a redirect
2464 - wfDebug( __METHOD__ . ": not a redirect\n" );
2465 - return false;
2466 - }
2467 -
2468 - # Does the article have a history?
2469 - $row = $dbw->selectRow( array('page','revision'),
2470 - array( 'rev_id' ),
2471 - array( 'page_namespace' => $this->mNamespace, 'page_title' => $this->mDbkeyform,
2472 - 'page_id=rev_page AND page_latest != rev_id'
2473 - ), $fname, 'FOR UPDATE'
2474 - );
2475 -
2476 - # Return true if there was no history
2477 - return $row === false;
2478 - }
2479 -
2480 - /**
24812449 * Can this title be added to a user's watchlist?
24822450 *
24832451 * @return bool
Index: trunk/phase3/includes/SpecialContributions.php
@@ -171,7 +171,7 @@
172172 }
173173 $histlink='('.$sk->makeKnownLinkObj( $page, $this->messages['hist'], 'action=history' ) . ')';
174174
175 - $comment = $wgContLang->getDirMark() . $sk->revComment( $rev, false, true );
 175+ $comment = $wgContLang->getDirMark() . $sk->revComment( $rev );
176176 $d = $wgLang->timeanddate( wfTimestamp( TS_MW, $row->rev_timestamp ), true );
177177
178178 if( $this->target == 'newbies' ) {
Index: trunk/phase3/includes/filerepo/LocalFile.php
@@ -46,8 +46,7 @@
4747 $sha1, # SHA-1 base 36 content hash
4848 $dataLoaded, # Whether or not all this has been loaded from the database (loadFromXxx)
4949 $upgraded, # Whether the row was upgraded on load
50 - $locked, # True if the image row is locked
51 - $deleted; # Bitfield akin to rev_deleted
 50+ $locked; # True if the image row is locked
5251
5352 /**#@-*/
5453
@@ -237,13 +236,8 @@
238237 $this->$name = $value;
239238 }
240239 $this->fileExists = true;
241 - // Check if the file is hidden...
242 - if( $this->isDeleted(File::DELETED_FILE) ) {
243 - $this->fileExists = false; // treat as not existing
244 - } else {
245 - // Check for rows from a previous schema, quietly upgrade them
246 - $this->maybeUpgradeRow();
247 - }
 240+ // Check for rows from a previous schema, quietly upgrade them
 241+ $this->maybeUpgradeRow();
248242 }
249243
250244 /**
@@ -578,9 +572,7 @@
579573 $this->historyRes = $dbr->select( 'image',
580574 array(
581575 '*',
582 - "'' AS oi_archive_name",
583 - '0 as oi_deleted',
584 - 'img_sha1'
 576+ "'' AS oi_archive_name"
585577 ),
586578 array( 'img_name' => $this->title->getDBkey() ),
587579 __METHOD__
@@ -749,7 +741,7 @@
750742 'oi_media_type' => 'img_media_type',
751743 'oi_major_mime' => 'img_major_mime',
752744 'oi_minor_mime' => 'img_minor_mime',
753 - 'oi_sha1' => 'img_sha1'
 745+ 'oi_sha1' => 'img_sha1',
754746 ), array( 'img_name' => $this->getName() ), __METHOD__
755747 );
756748
@@ -865,9 +857,9 @@
866858 * @param $reason
867859 * @return FileRepoStatus object.
868860 */
869 - function delete( $reason, $suppress=false ) {
 861+ function delete( $reason ) {
870862 $this->lock();
871 - $batch = new LocalFileDeleteBatch( $this, $reason, $suppress );
 863+ $batch = new LocalFileDeleteBatch( $this, $reason );
872864 $batch->addCurrent();
873865
874866 # Get old version relative paths
@@ -903,9 +895,9 @@
904896 * @throws MWException or FSException on database or filestore failure
905897 * @return FileRepoStatus object.
906898 */
907 - function deleteOld( $archiveName, $reason, $suppress=false ) {
 899+ function deleteOld( $archiveName, $reason ) {
908900 $this->lock();
909 - $batch = new LocalFileDeleteBatch( $this, $reason, $suppress );
 901+ $batch = new LocalFileDeleteBatch( $this, $reason );
910902 $batch->addOld( $archiveName );
911903 $status = $batch->execute();
912904 $this->unlock();
@@ -916,21 +908,22 @@
917909 return $status;
918910 }
919911
920 - /*
 912+ /**
921913 * Restore all or specified deleted revisions to the given file.
922914 * Permissions and logging are left to the caller.
923915 *
924916 * May throw database exceptions on error.
925917 *
926 - * @param string $timestamp, restore all revisions since this time
 918+ * @param $versions set of record ids of deleted items to restore,
 919+ * or empty to restore all revisions.
927920 * @return FileRepoStatus
928921 */
929 - function restore( $timestamp = 0, $unsuppress = false ) {
 922+ function restore( $versions = array(), $unsuppress = false ) {
930923 $batch = new LocalFileRestoreBatch( $this );
931 - if ( !$timestamp ) {
 924+ if ( !$versions ) {
932925 $batch->addAll();
933926 } else {
934 - $batch->addAll( $timestamp );
 927+ $batch->addIds( $versions );
935928 }
936929 $status = $batch->execute();
937930 if ( !$status->ok ) {
@@ -1110,10 +1103,9 @@
11111104 var $file, $reason, $srcRels = array(), $archiveUrls = array(), $deletionBatch;
11121105 var $status;
11131106
1114 - function __construct( File $file, $reason = '', $suppress=false ) {
 1107+ function __construct( File $file, $reason = '' ) {
11151108 $this->file = $file;
11161109 $this->reason = $reason;
1117 - $this->suppress = $suppress;
11181110 $this->status = $file->repo->newGood();
11191111 }
11201112
@@ -1194,16 +1186,6 @@
11951187 $dotExt = $ext === '' ? '' : ".$ext";
11961188 $encExt = $dbw->addQuotes( $dotExt );
11971189 list( $oldRels, $deleteCurrent ) = $this->getOldRels();
1198 -
1199 - // Bitfields to further suppress the content
1200 - if ( $this->suppress ) {
1201 - $bitfield = 0;
1202 - // This should be 15...
1203 - $bitfield |= Revision::DELETED_TEXT;
1204 - $bitfield |= Revision::DELETED_COMMENT;
1205 - $bitfield |= Revision::DELETED_USER;
1206 - $bitfield |= Revision::DELETED_RESTRICTED;
1207 - }
12081190
12091191 if ( $deleteCurrent ) {
12101192 $concat = $dbw->buildConcat( array( "img_sha1", $encExt ) );
@@ -1215,7 +1197,7 @@
12161198 'fa_deleted_user' => $encUserId,
12171199 'fa_deleted_timestamp' => $encTimestamp,
12181200 'fa_deleted_reason' => $encReason,
1219 - 'fa_deleted' => $this->suppress ? $bitfield : 0,
 1201+ 'fa_deleted' => 0,
12201202
12211203 'fa_name' => 'img_name',
12221204 'fa_archive_name' => 'NULL',
@@ -1246,7 +1228,7 @@
12471229 'fa_deleted_user' => $encUserId,
12481230 'fa_deleted_timestamp' => $encTimestamp,
12491231 'fa_deleted_reason' => $encReason,
1250 - 'fa_deleted' => $this->suppress ? $bitfield : 'oi_deleted',
 1232+ 'fa_deleted' => 0,
12511233
12521234 'fa_name' => 'oi_name',
12531235 'fa_archive_name' => 'oi_archive_name',
@@ -1289,25 +1271,7 @@
12901272 wfProfileIn( __METHOD__ );
12911273
12921274 $this->file->lock();
1293 - // Use revisiondelete to handle private files
1294 - $privateFiles = array();
1295 - list( $oldRels, $deleteCurrent ) = $this->getOldRels();
1296 - $dbw = $this->file->repo->getMasterDB();
1297 - $revisionDeleter = new RevisionDeleter( $dbw );
1298 - if( !empty( $oldRels ) ) {
1299 - $res = $dbw->select( 'oldimage',
1300 - array( 'oi_archive_name', 'oi_sha1' ),
1301 - array( 'oi_name' => $this->file->getName(),
1302 - 'oi_archive_name IN (' . $dbw->makeList( array_keys( $oldRels ) ) . ')',
1303 - 'oi_deleted & '.File::DELETED_FILE => File::DELETED_FILE ),
1304 - __METHOD__ );
1305 - while( $row = $dbw->fetchObject( $res ) ) {
1306 - $title = $this->file->getTitle();
1307 - $oimage = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName( $title, $row->oi_archive_name );
1308 - $oimage->sha1 = $row->oi_sha1;
1309 - $privateFiles[$row->oi_archive_name] = $oimage;
1310 - }
1311 - }
 1275+
13121276 // Prepare deletion batch
13131277 $hashes = $this->getHashes();
13141278 $this->deletionBatch = array();
@@ -1315,8 +1279,7 @@
13161280 $dotExt = $ext === '' ? '' : ".$ext";
13171281 foreach ( $this->srcRels as $name => $srcRel ) {
13181282 // Skip files that have no hash (missing source)
1319 - // Move private files using revisiondelete
1320 - if ( isset($hashes[$name]) && !array_key_exists($name,$privateFiles) ) {
 1283+ if ( isset( $hashes[$name] ) ) {
13211284 $hash = $hashes[$name];
13221285 $key = $hash . $dotExt;
13231286 $dstRel = $this->file->repo->getDeletedHashPath( $key ) . $key;
@@ -1345,19 +1308,6 @@
13461309 $this->file->unlockAndRollback();
13471310 return $this->status;
13481311 }
1349 -
1350 - // Delete image/oldimage rows
1351 - $this->doDBDeletes();
1352 -
1353 - // Move private files to deletion archives
1354 - $revisionDeleter = new RevisionDeleter( $dbw );
1355 - foreach( $privateFiles as $name => $oimage ) {
1356 - $ok = $revisionDeleter->moveImageFromFileRepos( $oimage, 'hidden', 'deleted' );
1357 - if( $ok )
1358 - $status->successCount++;
1359 - else
1360 - $status->failCount++;
1361 - }
13621312
13631313 // Purge squid
13641314 if ( $wgUseSquid ) {
@@ -1369,6 +1319,9 @@
13701320 SquidUpdate::purge( $urls );
13711321 }
13721322
 1323+ // Delete image/oldimage rows
 1324+ $this->doDBDeletes();
 1325+
13731326 // Commit and return
13741327 $this->file->unlock();
13751328 wfProfileOut( __METHOD__ );
@@ -1382,13 +1335,12 @@
13831336 * Helper class for file undeletion
13841337 */
13851338 class LocalFileRestoreBatch {
1386 - var $file, $cleanupBatch, $ids, $all;
 1339+ var $file, $cleanupBatch, $ids, $all, $unsuppress = false;
13871340
1388 - function __construct( File $file, $unsuppress = false ) {
 1341+ function __construct( File $file ) {
13891342 $this->file = $file;
13901343 $this->cleanupBatch = $this->ids = array();
13911344 $this->ids = array();
1392 - $this->unsuppress = $unsuppress;
13931345 }
13941346
13951347 /**
@@ -1407,11 +1359,9 @@
14081360
14091361 /**
14101362 * Add all revisions of the file
1411 - * Can be all from $timestamp if given
14121363 */
1413 - function addAll( $timestamp = false ) {
 1364+ function addAll() {
14141365 $this->all = true;
1415 - $this->timestamp = $timestamp;
14161366 }
14171367
14181368 /**
@@ -1432,16 +1382,11 @@
14331383 $dbw = $this->file->repo->getMasterDB();
14341384 $status = $this->file->repo->newGood();
14351385
1436 - $revisionDeleter = new RevisionDeleter( $dbw );
1437 - $privateFiles = array();
1438 -
14391386 // Fetch all or selected archived revisions for the file,
14401387 // sorted from the most recent to the oldest.
14411388 $conditions = array( 'fa_name' => $this->file->getName() );
14421389 if( !$this->all ) {
14431390 $conditions[] = 'fa_id IN (' . $dbw->makeList( $this->ids ) . ')';
1444 - } else if( $this->timestamp ) {
1445 - $conditions[] = "fa_timestamp >= {$this->timestamp}";
14461391 }
14471392
14481393 $result = $dbw->select( 'filearchive', '*',
@@ -1458,7 +1403,12 @@
14591404 $archiveNames = array();
14601405 while( $row = $dbw->fetchObject( $result ) ) {
14611406 $idsPresent[] = $row->fa_id;
1462 -
 1407+ if ( $this->unsuppress ) {
 1408+ // Currently, fa_deleted flags fall off upon restore, lets be careful about this
 1409+ } else if ( ($row->fa_deleted & Revision::DELETED_RESTRICTED) && !$wgUser->isAllowed('hiderevision') ) {
 1410+ // Skip restoring file revisions that the user cannot restore
 1411+ continue;
 1412+ }
14631413 if ( $row->fa_name != $this->file->getName() ) {
14641414 $status->error( 'undelete-filename-mismatch', $wgLang->timeanddate( $row->fa_timestamp ) );
14651415 $status->failCount++;
@@ -1496,11 +1446,6 @@
14971447 }
14981448
14991449 if ( $first && !$exists ) {
1500 - // The live (current) version cannot be hidden!
1501 - if( $row->fa_deleted ) {
1502 - $this->file->unlock();
1503 - return $status;
1504 - }
15051450 // This revision will be published as the new current version
15061451 $destRel = $this->file->getRel();
15071452 $insertCurrent = array(
@@ -1547,21 +1492,13 @@
15481493 'oi_media_type' => $props['media_type'],
15491494 'oi_major_mime' => $props['major_mime'],
15501495 'oi_minor_mime' => $props['minor_mime'],
1551 - 'oi_deleted' => $this->unsuppress ? 0 : $row->fa_deleted,
 1496+ 'oi_deleted' => $row->fa_deleted,
15521497 'oi_sha1' => $sha1 );
15531498 }
15541499
15551500 $deleteIds[] = $row->fa_id;
1556 - // Use revisiondelete to handle private files
1557 - if( $row->fa_deleted & File::DELETED_FILE ) {
1558 - $title = $this->file->getTitle();
1559 - $oimage = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName( $title, $archiveName );
1560 - $oimage->sha1 = $sha1;
1561 - $privateFiles[$archiveName] = $oimage;
1562 - } else {
1563 - $storeBatch[] = array( $deletedUrl, 'public', $destRel );
1564 - $this->cleanupBatch[] = $row->fa_storage_key;
1565 - }
 1501+ $storeBatch[] = array( $deletedUrl, 'public', $destRel );
 1502+ $this->cleanupBatch[] = $row->fa_storage_key;
15661503 $first = false;
15671504 }
15681505 unset( $result );
@@ -1601,16 +1538,6 @@
16021539 array( 'fa_id IN (' . $dbw->makeList( $deleteIds ) . ')' ),
16031540 __METHOD__ );
16041541 }
1605 -
1606 - // Immediatly move to private files to hidden directory
1607 - $revisionDeleter = new RevisionDeleter( $dbw );
1608 - foreach ( $privateFiles as $oimage ) {
1609 - $ok = $revisionDeleter->moveImageFromFileRepos( $oimage, 'deleted', 'hidden' );
1610 - if( $ok )
1611 - $status->successCount++;
1612 - else
1613 - $status->failCount++;
1614 - }
16151542
16161543 if( $status->successCount > 0 ) {
16171544 if( !$exists ) {
Index: trunk/phase3/includes/filerepo/FSRepo.php
@@ -6,7 +6,7 @@
77 */
88
99 class FSRepo extends FileRepo {
10 - var $directory, $deletedDir, $hiddenDir, $url, $hashLevels, $deletedHashLevels;
 10+ var $directory, $deletedDir, $url, $hashLevels, $deletedHashLevels;
1111 var $fileFactory = array( 'UnregisteredLocalFile', 'newFromTitle' );
1212 var $oldFileFactory = false;
1313 var $pathDisclosureProtection = 'simple';
@@ -22,10 +22,7 @@
2323 $this->hashLevels = isset( $info['hashLevels'] ) ? $info['hashLevels'] : 2;
2424 $this->deletedHashLevels = isset( $info['deletedHashLevels'] ) ?
2525 $info['deletedHashLevels'] : $this->hashLevels;
26 - $this->hiddenHashLevels = isset( $info['hiddenHashLevels'] ) ?
27 - $info['hiddenHashLevels'] : $this->hashLevels;
2826 $this->deletedDir = isset( $info['deletedDir'] ) ? $info['deletedDir'] : false;
29 - $this->hiddenDir = isset( $info['hiddenDir'] ) ? $info['hiddenDir'] : false;
3027 }
3128
3229 /**
@@ -58,8 +55,6 @@
5956 return $this->directory;
6057 case 'temp':
6158 return "{$this->directory}/temp";
62 - case 'hidden':
63 - return $this->hiddenDir;
6459 case 'deleted':
6560 return $this->deletedDir;
6661 default:
@@ -76,8 +71,6 @@
7772 return $this->url;
7873 case 'temp':
7974 return "{$this->url}/temp";
80 - case 'hidden':
81 - return false; // no public URL
8275 case 'deleted':
8376 return false; // no public URL
8477 default:
@@ -424,7 +417,7 @@
425418 $status->error( 'filedeleteerror', $srcPath );
426419 $good = false;
427420 }
428 - } else {
 421+ } else{
429422 if ( !@rename( $srcPath, $archivePath ) ) {
430423 $status->error( 'filerenameerror', $srcPath, $archivePath );
431424 $good = false;
Index: trunk/phase3/includes/filerepo/File.php
@@ -380,17 +380,6 @@
381381 return $this->getPath() && file_exists( $this->path );
382382 }
383383
384 - /**
385 - * Returns true if file exists in the repository and can be included in a page.
386 - * It would be unsafe to include private images, making public thumbnails inadvertently
387 - *
388 - * @return boolean Whether file exists in the repository and is includable.
389 - * @public
390 - */
391 - function isVisible() {
392 - return $this->exists();
393 - }
394 -
395384 function getTransformScript() {
396385 if ( !isset( $this->transformScript ) ) {
397386 $this->transformScript = false;
@@ -611,7 +600,7 @@
612601 * STUB
613602 * Overridden by LocalFile
614603 */
615 - function purgeCache() {}
 604+ function purgeCache( $archiveFiles = array() ) {}
616605
617606 /**
618607 * Purge the file description page, but don't go after
@@ -923,13 +912,14 @@
924913 *
925914 * May throw database exceptions on error.
926915 *
927 - * @param string $timestamp, restore all revisions since this time
 916+ * @param $versions set of record ids of deleted items to restore,
 917+ * or empty to restore all revisions.
928918 * @return the number of file revisions restored if successful,
929919 * or false on failure
930920 * STUB
931921 * Overridden by LocalFile
932922 */
933 - function restore( $timestamp = 0, $Unsuppress=false ) {
 923+ function restore( $versions=array(), $Unsuppress=false ) {
934924 $this->readOnlyError();
935925 }
936926
Index: trunk/phase3/includes/filerepo/ArchivedFile.php
@@ -5,49 +5,24 @@
66 */
77 class ArchivedFile
88 {
9 - function ArchivedFile( $title, $id=0, $key='' ) {
10 - if( !is_object( $title ) ) {
11 - throw new MWException( 'ArchivedFile constructor given bogus title.' );
12 - }
13 - $this->id = -1;
14 - $this->title = $title;
15 - $this->name = $title->getDBKey();
16 - $this->group = '';
17 - $this->key = '';
18 - $this->size = 0;
19 - $this->bits = 0;
20 - $this->width = 0;
21 - $this->height = 0;
22 - $this->metaData = '';
23 - $this->mime = "unknown/unknown";
24 - $this->type = '';
25 - $this->description = '';
26 - $this->user = 0;
27 - $this->userText = '';
28 - $this->timestamp = NULL;
29 - $this->deleted = 0;
30 - # BC, load if these are specified
31 - if( $id || $key ) {
32 - $this->load();
33 - }
34 - }
35 -
369 /**
37 - * Loads a file object from the filearchive table
 10+ * Returns a file object from the filearchive table
 11+ * @param $title, the corresponding image page title
 12+ * @param $id, the image id, a unique key
 13+ * @param $key, optional storage key
3814 * @return ResultWrapper
3915 */
40 - function load() {
41 - if( !is_object( $this->title ) ) {
 16+ function ArchivedFile( $title, $id=0, $key='' ) {
 17+ if( !is_object( $title ) ) {
4218 throw new MWException( 'ArchivedFile constructor given bogus title.' );
4319 }
44 - $conds = ($this->id) ? "fa_id = {$this->id}" : "fa_storage_key = '{$this->key}'";
45 - if( $this->title->getNamespace() == NS_IMAGE ) {
 20+ $conds = ($id) ? "fa_id = $id" : "fa_storage_key = '$key'";
 21+ if( $title->getNamespace() == NS_IMAGE ) {
4622 $dbr = wfGetDB( DB_SLAVE );
4723 $res = $dbr->select( 'filearchive',
4824 array(
4925 'fa_id',
5026 'fa_name',
51 - 'fa_archive_name',
5227 'fa_storage_key',
5328 'fa_storage_group',
5429 'fa_size',
@@ -64,7 +39,7 @@
6540 'fa_timestamp',
6641 'fa_deleted' ),
6742 array(
68 - 'fa_name' => $this->title->getDBKey(),
 43+ 'fa_name' => $title->getDbKey(),
6944 $conds ),
7045 __METHOD__,
7146 array( 'ORDER BY' => 'fa_timestamp DESC' ) );
@@ -77,23 +52,22 @@
7853 $row = $ret->fetchObject();
7954
8055 // initialize fields for filestore image object
81 - $this->id = intval($row->fa_id);
82 - $this->name = $row->fa_name;
83 - $this->archive_name = $row->fa_archive_name;
84 - $this->group = $row->fa_storage_group;
85 - $this->key = $row->fa_storage_key;
86 - $this->size = $row->fa_size;
87 - $this->bits = $row->fa_bits;
88 - $this->width = $row->fa_width;
89 - $this->height = $row->fa_height;
90 - $this->metaData = $row->fa_metadata;
91 - $this->mime = "$row->fa_major_mime/$row->fa_minor_mime";
92 - $this->type = $row->fa_media_type;
93 - $this->description = $row->fa_description;
94 - $this->user = $row->fa_user;
95 - $this->userText = $row->fa_user_text;
96 - $this->timestamp = $row->fa_timestamp;
97 - $this->deleted = $row->fa_deleted;
 56+ $this->mId = intval($row->fa_id);
 57+ $this->mName = $row->fa_name;
 58+ $this->mGroup = $row->fa_storage_group;
 59+ $this->mKey = $row->fa_storage_key;
 60+ $this->mSize = $row->fa_size;
 61+ $this->mBits = $row->fa_bits;
 62+ $this->mWidth = $row->fa_width;
 63+ $this->mHeight = $row->fa_height;
 64+ $this->mMetaData = $row->fa_metadata;
 65+ $this->mMime = "$row->fa_major_mime/$row->fa_minor_mime";
 66+ $this->mType = $row->fa_media_type;
 67+ $this->mDescription = $row->fa_description;
 68+ $this->mUser = $row->fa_user;
 69+ $this->mUserText = $row->fa_user_text;
 70+ $this->mTimestamp = $row->fa_timestamp;
 71+ $this->mDeleted = $row->fa_deleted;
9872 } else {
9973 throw new MWException( 'This title does not correspond to an image page.' );
10074 return;
@@ -102,40 +76,12 @@
10377 }
10478
10579 /**
106 - * Loads a file object from the filearchive table
107 - * @return ResultWrapper
108 - */
109 - public static function newFromRow( $row ) {
110 - $file = new ArchivedFile( Title::makeTitle( NS_IMAGE, $row->fa_name ) );
111 -
112 - $file->id = intval($row->fa_id);
113 - $file->name = $row->fa_name;
114 - $file->archive_name = $row->fa_archive_name;
115 - $file->group = $row->fa_storage_group;
116 - $file->key = $row->fa_storage_key;
117 - $file->size = $row->fa_size;
118 - $file->bits = $row->fa_bits;
119 - $file->width = $row->fa_width;
120 - $file->height = $row->fa_height;
121 - $file->metaData = $row->fa_metadata;
122 - $file->mime = "$row->fa_major_mime/$row->fa_minor_mime";
123 - $file->type = $row->fa_media_type;
124 - $file->description = $row->fa_description;
125 - $file->user = $row->fa_user;
126 - $file->userText = $row->fa_user_text;
127 - $file->timestamp = $row->fa_timestamp;
128 - $file->deleted = $row->fa_deleted;
129 -
130 - return $file;
131 - }
132 -
133 - /**
13480 * int $field one of DELETED_* bitfield constants
13581 * for file or revision rows
13682 * @return bool
13783 */
13884 function isDeleted( $field ) {
139 - return ($this->deleted & $field) == $field;
 85+ return ($this->mDeleted & $field) == $field;
14086 }
14187
14288 /**
@@ -145,16 +91,18 @@
14692 * @return bool
14793 */
14894 function userCan( $field ) {
149 - if( isset($this->deleted) && ($this->deleted & $field) == $field ) {
 95+ if( isset($this->mDeleted) && ($this->mDeleted & $field) == $field ) {
15096 // images
15197 global $wgUser;
152 - $permission = ( $this->deleted & File::DELETED_RESTRICTED ) == File::DELETED_RESTRICTED
 98+ $permission = ( $this->mDeleted & File::DELETED_RESTRICTED ) == File::DELETED_RESTRICTED
15399 ? 'hiderevision'
154100 : 'deleterevision';
155 - wfDebug( "Checking for $permission due to $field match on $this->deleted\n" );
 101+ wfDebug( "Checking for $permission due to $field match on $this->mDeleted\n" );
156102 return $wgUser->isAllowed( $permission );
157103 } else {
158104 return true;
159105 }
160106 }
161107 }
 108+
 109+
Index: trunk/phase3/includes/filerepo/FileRepo.php
@@ -6,7 +6,6 @@
77 */
88 abstract class FileRepo {
99 const DELETE_SOURCE = 1;
10 - const FIND_PRIVATE = 1;
1110 const OVERWRITE = 2;
1211 const OVERWRITE_SAME = 4;
1312
@@ -77,23 +76,20 @@
7877 *
7978 * @param mixed $time 14-character timestamp, or false for the current version
8079 */
81 - function findFile( $title, $time = false, $flags = 0 ) {
 80+ function findFile( $title, $time = false ) {
8281 # First try the current version of the file to see if it precedes the timestamp
8382 $img = $this->newFile( $title );
84 - # Check if the image exists and is of the specified timestamp
85 - if ( $img->exists() && ( !$time || $img->getTimestamp()==$time ) ) {
 83+ if ( !$img ) {
 84+ return false;
 85+ }
 86+ if ( $img->exists() && ( !$time || $img->getTimestamp() <= $time ) ) {
8687 return $img;
8788 }
8889 # Now try an old version of the file
8990 $img = $this->newFile( $title, $time );
9091 if ( $img->exists() ) {
91 - if( !$img->isDeleted(File::DELETED_FILE) ) {
92 - return $img;
93 - } else if( ($flags & FileRepo::FIND_PRIVATE) && $img->userCan(File::DELETED_FILE) ) {
94 - return $img;
95 - }
 92+ return $img;
9693 }
97 - return false;
9894 }
9995
10096 /**
Index: trunk/phase3/includes/filerepo/OldLocalFile.php
@@ -56,10 +56,6 @@
5757 function isOld() {
5858 return true;
5959 }
60 -
61 - function isVisible() {
62 - return $this->exists() && !$this->isDeleted(File::DELETED_FILE);
63 - }
6460
6561 /**
6662 * Try to load file metadata from memcached. Returns true on success.
@@ -183,8 +179,10 @@
184180 function getCacheFields( $prefix = 'img_' ) {
185181 $fields = parent::getCacheFields( $prefix );
186182 $fields[] = $prefix . 'archive_name';
187 - $fields[] = $prefix . 'deleted';
188 -
 183+
 184+ // XXX: Temporary hack before schema update
 185+ //$fields = array_diff( $fields, array(
 186+ // 'oi_media_type', 'oi_major_mime', 'oi_minor_mime', 'oi_metadata' ) );
189187 return $fields;
190188 }
191189
@@ -228,35 +226,7 @@
229227 );
230228 wfProfileOut( __METHOD__ );
231229 }
232 -
233 - /**
234 - * int $field one of DELETED_* bitfield constants
235 - * for file or revision rows
236 - * @return bool
237 - */
238 - function isDeleted( $field ) {
239 - return ($this->deleted & $field) == $field;
240 - }
241 -
242 - /**
243 - * Determine if the current user is allowed to view a particular
244 - * field of this FileStore image file, if it's marked as deleted.
245 - * @param int $field
246 - * @return bool
247 - */
248 - function userCan( $field ) {
249 - if( isset($this->deleted) && ($this->deleted & $field) == $field ) {
250 - global $wgUser;
251 - $permission = ( $this->deleted & File::DELETED_RESTRICTED ) == File::DELETED_RESTRICTED
252 - ? 'hiderevision'
253 - : 'deleterevision';
254 - wfDebug( "Checking for $permission due to $field match on $this->mDeleted\n" );
255 - return $wgUser->isAllowed( $permission );
256 - } else {
257 - return true;
258 - }
259 - }
260 -
261230 }
262231
263232
 233+
Index: trunk/phase3/includes/ImagePage.php
@@ -416,23 +416,22 @@
417417
418418 if ( $line ) {
419419 $list = new ImageHistoryList( $sk, $this->img );
420 - // Our top image
421420 $file = $this->repo->newFileFromRow( $line );
422421 $dims = $file->getDimensionsString();
423422 $s = $list->beginImageHistoryList() .
424423 $list->imageHistoryLine( true, wfTimestamp(TS_MW, $line->img_timestamp),
425 - $this->mTitle->getDBkey(), $line->img_user,
426 - $line->img_user_text, $line->img_size, $line->img_description, $dims,
427 - $line->oi_deleted, $line->img_sha1
 424+ $this->mTitle->getDBkey(), $line->img_user,
 425+ $line->img_user_text, $line->img_size, $line->img_description,
 426+ $dims
428427 );
429 - // old image versions
 428+
430429 while ( $line = $this->img->nextHistoryLine() ) {
431430 $file = $this->repo->newFileFromRow( $line );
432431 $dims = $file->getDimensionsString();
433432 $s .= $list->imageHistoryLine( false, $line->oi_timestamp,
434433 $line->oi_archive_name, $line->oi_user,
435434 $line->oi_user_text, $line->oi_size, $line->oi_description,
436 - $dims, $line->oi_deleted, $line->oi_sha1
 435+ $dims
437436 );
438437 }
439438 $s .= $list->endImageHistoryList();
@@ -551,7 +550,7 @@
552551 . $wgOut->parse( wfMsgNoTrans( 'filehist-help' ) )
553552 . Xml::openElement( 'table', array( 'class' => 'filehistory' ) ) . "\n"
554553 . '<tr><td></td>'
555 - . ( $this->img->isLocal() && $wgUser->isAllowed( 'deleterevision' ) ? '<td></td>' : '' )
 554+ . ( $this->img->isLocal() && $wgUser->isAllowed( 'delete' ) ? '<td></td>' : '' )
556555 . '<th>' . wfMsgHtml( 'filehist-datetime' ) . '</th>'
557556 . '<th>' . wfMsgHtml( 'filehist-user' ) . '</th>'
558557 . '<th>' . wfMsgHtml( 'filehist-dimensions' ) . '</th>'
@@ -564,48 +563,30 @@
565564 return "</table>\n";
566565 }
567566
568 - public function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description, $dims,
569 - $deleted, $sha1 ) {
570 - global $wgUser, $wgLang, $wgContLang, $wgTitle;
 567+ public function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description, $dims ) {
 568+ global $wgUser, $wgLang, $wgContLang;
571569 $local = $this->img->isLocal();
572 - $row = '<td>';
 570+ $row = '';
573571
574572 // Deletion link
575 - if( $iscur && $local && $wgUser->isAllowed( 'delete' ) ) {
 573+ if( $local && $wgUser->isAllowed( 'delete' ) ) {
 574+ $row .= '<td>';
576575 $q = array();
577576 $q[] = 'action=delete';
578 - $q[] = 'image=' . $this->title->getPartialUrl();
 577+ if( !$iscur )
 578+ $q[] = 'oldimage=' . urlencode( $img );
579579 $row .= '(' . $this->skin->makeKnownLinkObj(
580580 $this->title,
581581 wfMsgHtml( $iscur ? 'filehist-deleteall' : 'filehist-deleteone' ),
582582 implode( '&', $q )
583583 ) . ')';
584 - $row .= '</td><td>';
 584+ $row .= '</td>';
585585 }
586586
587 - if( !$iscur && $local && $wgUser->isAllowed( 'deleterevision' ) ) {
588 - $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
589 - if( !$this->userCan($deleted,Image::DELETED_RESTRICTED) ) {
590 - // If file was hidden from sysops
591 - $del = wfMsgHtml( 'rev-delundel' );
592 - } else {
593 - // If the file was hidden, link to sha-1
594 - list($ts,$name) = explode('!',$img,2);
595 - $del = $this->skin->makeKnownLinkObj( $revdel, wfMsg( 'rev-delundel' ),
596 - 'target=' . urlencode( $wgTitle->getPrefixedText() ) .
597 - '&oldimage=' . urlencode( $ts ) );
598 - // Bolden oversighted content
599 - if( $this->isDeleted($deleted,Image::DELETED_RESTRICTED) )
600 - $del = "<strong>$del</strong>";
601 - }
602 - $row .= "<tt>(<small>$del</small>)</tt></td><td> ";
603 - }
604 -
605587 // Reversion link/current indicator
 588+ $row .= '<td>';
606589 if( $iscur ) {
607 - $row .= ' (' . wfMsgHtml( 'filehist-current' ) . ')';
608 - } elseif( $this->isDeleted($deleted,Image::DELETED_FILE) ) {
609 - $row .= '(' . wfMsgHtml('filehist-revert') . ')';
 590+ $row .= '(' . wfMsgHtml( 'filehist-current' ) . ')';
610591 } elseif( $local && $wgUser->isLoggedIn() && $this->title->userCan( 'edit' ) ) {
611592 $q = array();
612593 $q[] = 'action=revert';
@@ -621,32 +602,18 @@
622603
623604 // Date/time and image link
624605 $row .= '<td>';
625 - if( !$this->userCan($deleted,Image::DELETED_FILE) ) {
626 - # Don't link to unviewable files
627 - $row .= '<span class="history-deleted">' . $wgLang->timeAndDate( $timestamp, true ) . '</span>';
628 - } else if( $this->isDeleted($deleted,Image::DELETED_FILE) ) {
629 - $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
630 - # Make a link to review the image
631 - $url = $this->skin->makeKnownLinkObj( $revdel, $wgLang->timeAndDate( $timestamp, true ),
632 - "target=".$wgTitle->getPrefixedText()."&file=$sha1.".$this->img->getExtension() );
633 - $row .= '<span class="history-deleted">'.$url.'</span>';
634 - } else {
635 - $url = $iscur ? $this->img->getUrl() : $this->img->getArchiveUrl( $img );
636 - $row .= Xml::element( 'a',
637 - array( 'href' => $url ),
638 - $wgLang->timeAndDate( $timestamp, true ) );
639 - }
640 -
 606+ $url = $iscur ? $this->img->getUrl() : $this->img->getArchiveUrl( $img );
 607+ $row .= Xml::element(
 608+ 'a',
 609+ array( 'href' => $url ),
 610+ $wgLang->timeAndDate( $timestamp, true )
 611+ );
641612 $row .= '</td>';
642613
643614 // Uploading user
644615 $row .= '<td>';
645616 if( $local ) {
646 - // Hide deleted usernames
647 - if( $this->isDeleted($deleted,Image::DELETED_USER) )
648 - $row .= '<span class="history-deleted">' . wfMsgHtml( 'rev-deleted-user' ) . '</span>';
649 - else
650 - $row .= $this->skin->userLink( $user, $usertext ) . $this->skin->userToolLinks( $user, $usertext );
 617+ $row .= $this->skin->userLink( $user, $usertext ) . $this->skin->userToolLinks( $user, $usertext );
651618 } else {
652619 $row .= htmlspecialchars( $usertext );
653620 }
@@ -658,45 +625,10 @@
659626 // File size
660627 $row .= '<td class="mw-imagepage-filesize">' . $this->skin->formatSize( $size ) . '</td>';
661628
662 - // Don't show deleted descriptions
663 - if ( $this->isDeleted($deleted,Image::DELETED_COMMENT) )
664 - $row .= '<td><span class="history-deleted">' . wfMsgHtml('rev-deleted-comment') . '</span></td>';
665 - else
666 - $row .= '<td>' . $this->skin->commentBlock( $description, $this->title ) . '</td>';
 629+ // Comment
 630+ $row .= '<td>' . $this->skin->formatComment( $description, $this->title ) . '</td>';
667631
668632 return "<tr>{$row}</tr>\n";
669633 }
670 -
671 - /**
672 - * int $field one of DELETED_* bitfield constants
673 - * for file or revision rows
674 - * @param int $bitfield
675 - * @param int $field
676 - * @return bool
677 - */
678 - function isDeleted( $bitfield, $field ) {
679 - return ($bitfield & $field) == $field;
680 - }
681 -
682 - /**
683 - * Determine if the current user is allowed to view a particular
684 - * field of this FileStore image file, if it's marked as deleted.
685 - * @param int $bitfield
686 - * @param int $field
687 - * @return bool
688 - */
689 - function userCan( $bitfield, $field ) {
690 - if( ($bitfield & $field) == $field ) {
691 - // images
692 - global $wgUser;
693 - $permission = ( $bitfield & File::DELETED_RESTRICTED ) == File::DELETED_RESTRICTED
694 - ? 'hiderevision'
695 - : 'deleterevision';
696 - wfDebug( "Checking for $permission due to $field match on $bitfield\n" );
697 - return $wgUser->isAllowed( $permission );
698 - } else {
699 - return true;
700 - }
701 - }
702634
703635 }
Index: trunk/phase3/includes/SpecialIpblocklist.php
@@ -322,13 +322,13 @@
323323 $titleObj = SpecialPage::getTitleFor( "Ipblocklist" );
324324 $unblocklink = ' (' . $sk->makeKnownLinkObj($titleObj, $msg['unblocklink'], 'action=unblock&id=' . urlencode( $block->mId ) ) . ')';
325325 }
326 -
 326+
327327 $comment = $sk->commentBlock( $block->mReason );
328 -
 328+
329329 $s = "{$line} $comment";
330330 if ( $block->mHideName )
331331 $s = '<span class="history-deleted">' . $s . '</span>';
332 -
 332+
333333 wfProfileOut( __METHOD__ );
334334 return "<li>$s $unblocklink</li>\n";
335335 }
Index: trunk/phase3/includes/SpecialLog.php
@@ -50,24 +50,7 @@
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 newRowFromID( $logid ) {
62 - $fname = 'LogReader::newFromTitle';
6354
64 - $dbr = wfGetDB( DB_SLAVE );
65 - $row = $dbr->selectRow( 'logging', array('*'),
66 - array('log_id' => intval($logid) ),
67 - $fname );
68 -
69 - return $row;
70 - }
71 -
7255 /**
7356 * Basic setup and applies the limiting factors from the WebRequest object.
7457 * @param WebRequest $request
@@ -97,31 +80,10 @@
9881
9982 /**
10083 * Set the log reader to return only entries of the given type.
101 - * Type restrictions enforced here
10284 * @param string $type A log type ('upload', 'delete', etc)
10385 * @private
10486 */
10587 function limitType( $type ) {
106 - global $wgLogRestrictions, $wgUser;
107 - // Reset the array, clears extra "where" clauses when $par is used
108 - $this->whereClauses = $hiddenLogs = array();
109 - // Exclude logs this user can't see
110 - if( isset($wgLogRestrictions) ) {
111 - if( isset($wgLogRestrictions[$type]) && !$wgUser->isAllowed( $wgLogRestrictions[$type] ) )
112 - return false;
113 - // Don't show private logs to unpriviledged users or
114 - // when not specifically requested.
115 - foreach( $wgLogRestrictions as $logtype => $right ) {
116 - if( !$wgUser->isAllowed( $right ) || empty($type) ) {
117 - $safetype = $this->db->strencode( $logtype );
118 - $hiddenLogs[] = "'$safetype'";
119 - }
120 - }
121 - if( !empty($hiddenLogs) ) {
122 - $this->whereClauses[] = 'log_type NOT IN('.implode(',',$hiddenLogs).')';
123 - }
124 - }
125 -
12688 if( empty( $type ) ) {
12789 return false;
12890 }
@@ -199,16 +161,11 @@
200162 * @private
201163 */
202164 function getQuery() {
203 - global $wgAllowLogDeletion;
204 -
205165 $logging = $this->db->tableName( "logging" );
206166 $sql = "SELECT /*! STRAIGHT_JOIN */ log_type, log_action, log_timestamp,
207 - log_user, user_name, log_namespace, log_title, page_id,
208 - log_comment, log_params, log_deleted ";
209 - if( $wgAllowLogDeletion )
210 - $sql .= ", log_id ";
211 -
212 - $sql .= "FROM $logging ";
 167+ log_user, user_name,
 168+ log_namespace, log_title, page_id,
 169+ log_comment, log_params FROM $logging ";
213170 if( !empty( $this->joinClauses ) ) {
214171 $sql .= implode( ' ', $this->joinClauses );
215172 }
@@ -276,7 +233,7 @@
277234 $this->db->freeResult( $res );
278235 return $ret;
279236 }
280 -
 237+
281238 }
282239
283240 /**
@@ -284,12 +241,8 @@
285242 * @addtogroup SpecialPage
286243 */
287244 class LogViewer {
288 - const DELETED_ACTION = 1;
289 - const DELETED_COMMENT = 2;
290 - const DELETED_USER = 4;
291 - const DELETED_RESTRICTED = 8;
292 -
293245 const NO_ACTION_LINK = 1;
 246+
294247 /**
295248 * @var LogReader $reader
296249 */
@@ -306,22 +259,8 @@
307260 global $wgUser;
308261 $this->skin = $wgUser->getSkin();
309262 $this->reader =& $reader;
310 - $this->preCacheMessages();
311263 $this->flags = $flags;
312264 }
313 -
314 - /**
315 - * As we use the same small set of messages in various methods and that
316 - * they are called often, we call them once and save them in $this->message
317 - */
318 - function preCacheMessages() {
319 - // Precache various messages
320 - if( !isset( $this->message ) ) {
321 - foreach( explode(' ', 'viewpagelogs revhistory filehist rev-delundel' ) as $msg ) {
322 - $this->message[$msg] = wfMsgExt( $msg, array( 'escape') );
323 - }
324 - }
325 - }
326265
327266 /**
328267 * Take over the whole output page in $wgOut with the log display.
@@ -339,84 +278,8 @@
340279 $this->showError( $wgOut );
341280 }
342281 }
343 -
344 - /**
345 - * Fetch event's user id if it's available to all users
346 - * @return int
347 - */
348 - static function getUser( $event ) {
349 - if( $this->isDeleted( $event, Revision::DELETED_USER ) ) {
350 - return 0;
351 - } else {
352 - return $event->log_user;
353 - }
354 - }
355282
356283 /**
357 - * Fetch event's user id without regard for the current user's permissions
358 - * @return string
359 - */
360 - static function getRawUser( $event ) {
361 - return $event->log_user;
362 - }
363 -
364 - /**
365 - * Fetch event's username if it's available to all users
366 - * @return string
367 - */
368 - static function getUserText( $event ) {
369 - if( $this->isDeleted( $event, Revision::DELETED_USER ) ) {
370 - return "";
371 - } else {
372 - if ( isset($event->user_name) ) {
373 - return $event->user_name;
374 - } else {
375 - return User::whoIs( $event->log_user );
376 - }
377 - }
378 - }
379 -
380 - /**
381 - * Fetch event's username without regard for view restrictions
382 - * @return string
383 - */
384 - static function getRawUserText( $event ) {
385 - if ( isset($event->user_name) ) {
386 - return $event->user_name;
387 - } else {
388 - return User::whoIs( $event->log_user );
389 - }
390 - }
391 -
392 - /**
393 - * Fetch event comment if it's available to all users
394 - * @return string
395 - */
396 - static function getComment( $event ) {
397 - if( $this->isDeleted( $event, Revision::DELETED_COMMENT ) ) {
398 - return "";
399 - } else {
400 - return $event->log_comment;
401 - }
402 - }
403 -
404 - /**
405 - * Fetch event comment without regard for the current user's permissions
406 - * @return string
407 - */
408 - static function getRawComment( $event ) {
409 - return $event->log_comment;
410 - }
411 -
412 - /**
413 - * Returns the title of the page associated with this entry.
414 - * @return Title
415 - */
416 - static function getTitle( $event ) {
417 - return Title::makeTitle( $event->log_namespace, $event->log_title );
418 - }
419 -
420 - /**
421284 * Load the data from the linked LogReader
422285 * Preload the link cache
423286 * Initialise numResults
@@ -500,154 +363,54 @@
501364 } else {
502365 $linkCache->addBadLinkObj( $title );
503366 }
504 - // User links
505 - $userLink = $this->skin->logUserTools( $s, true );
506 - // Comment
507 - if( $s->log_action == 'create2' ) {
508 - $comment = ''; // Suppress from old account creations, useless and can contain incorrect links
509 - } else if( $s->log_deleted & self::DELETED_COMMENT ) {
510 - $comment = '<span class="history-deleted">' . wfMsgHtml('rev-deleted-comment') . '</span>';
511 - } else {
512 - $comment = $wgContLang->getDirMark() . $this->skin->commentBlock( $s->log_comment );
513 - }
514 -
515 - $paramArray = LogPage::extractParams( $s->log_params );
516 - $revert = ''; $del = '';
517 -
518 - // Some user can hide log items and have review links
519 - if( $wgUser->isAllowed( 'deleterevision' ) ) {
520 - $del = $this->showhideLinks( $s, $title );
521 - }
522 -
523 - // Show restore/unprotect/unblock
524 - $revert = $this->showReviewLinks( $s, $title, $paramArray );
525 -
526 - // Event description
527 - if ( $s->log_deleted & self::DELETED_ACTION )
528 - $action = '<span class="history-deleted">' . wfMsgHtml('rev-deleted-event') . '</span>';
529 - else
530 - $action = LogPage::actionText( $s->log_type, $s->log_action, $title, $this->skin, $paramArray, true );
531 -
532 - return "<li><tt>$del</tt> $time $userLink $action $comment $revert</li>";
533 - }
534367
535 - /**
536 - * @param $s, row object
537 - * @param $s, title object
538 - * @private
539 - */
540 - function showhideLinks( $s, $title ) {
541 - global $wgAllowLogDeletion;
542 -
543 - if( !$wgAllowLogDeletion )
544 - return "";
545 -
546 - $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
547 - // If event was hidden from sysops
548 - if( !self::userCan( $s, Revision::DELETED_RESTRICTED ) ) {
549 - $del = $this->message['rev-delundel'];
550 - } else if( $s->log_type == 'oversight' ) {
551 - return ''; // No one should be hiding from the oversight log
552 - } else {
553 - $del = $this->skin->makeKnownLinkObj( $revdel, $this->message['rev-delundel'], 'logid='.$s->log_id );
554 - // Bolden oversighted content
555 - if( self::isDeleted( $s, Revision::DELETED_RESTRICTED ) )
556 - $del = "<strong>$del</strong>";
557 - }
558 - return "(<small>$del</small>)";
559 - }
560 -
561 - /**
562 - * @param $s, row object
563 - * @param $title, title object
564 - * @param $s, param array
565 - * @private
566 - */
567 - function showReviewLinks( $s, $title, $paramArray ) {
568 - global $wgUser;
569 -
 368+ $userLink = $this->skin->userLink( $s->log_user, $s->user_name ) . $this->skin->userToolLinksRedContribs( $s->log_user, $s->user_name );
 369+ $comment = $wgContLang->getDirMark() . $this->skin->commentBlock( $s->log_comment );
 370+ $paramArray = LogPage::extractParams( $s->log_params );
570371 $revert = '';
571 - // Don't give away the page name
572 - if( self::isDeleted($s,self::DELETED_ACTION) )
573 - return $revert;
 372+ // show revertmove link
 373+ if ( !( $this->flags & self::NO_ACTION_LINK ) ) {
 374+ if ( $s->log_type == 'move' && isset( $paramArray[0] ) ) {
 375+ $destTitle = Title::newFromText( $paramArray[0] );
 376+ if ( $destTitle ) {
 377+ $revert = '(' . $this->skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Movepage' ),
 378+ wfMsg( 'revertmove' ),
 379+ 'wpOldTitle=' . urlencode( $destTitle->getPrefixedDBkey() ) .
 380+ '&wpNewTitle=' . urlencode( $title->getPrefixedDBkey() ) .
 381+ '&wpReason=' . urlencode( wfMsgForContent( 'revertmove' ) ) .
 382+ '&wpMovetalk=0' ) . ')';
 383+ }
 384+ // show undelete link
 385+ } elseif ( $s->log_action == 'delete' && $wgUser->isAllowed( 'delete' ) ) {
 386+ $revert = '(' . $this->skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Undelete' ),
 387+ wfMsg( 'undeletebtn' ) ,
 388+ 'target='. urlencode( $title->getPrefixedDBkey() ) ) . ')';
574389
575 - if( $this->flags & self::NO_ACTION_LINK ) {
576 - return $revert;
577 - }
578 - // Show revertmove link
579 - if( $s->log_type == 'move' && isset( $paramArray[0] ) ) {
580 - $destTitle = Title::newFromText( $paramArray[0] );
581 - if ( $destTitle ) {
582 - $revert = $this->skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Movepage' ),
583 - wfMsg( 'revertmove' ),
584 - 'wpOldTitle=' . urlencode( $destTitle->getPrefixedDBkey() ) .
585 - '&wpNewTitle=' . urlencode( $title->getPrefixedDBkey() ) .
586 - '&wpReason=' . urlencode( wfMsgForContent( 'revertmove' ) ) .
587 - '&wpMovetalk=0' );
588 - }
589 - // show undelete link
590 - } else if( $s->log_action == 'delete' && $wgUser->isAllowed( 'delete' ) ) {
591 - $revert = $this->skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Undelete' ),
592 - wfMsg( 'undeletebtn' ) ,
593 - 'target='. urlencode( $title->getPrefixedDBkey() ) );
594 - // show unblock link
595 - } elseif( $s->log_action == 'block' && $wgUser->isAllowed( 'block' ) ) {
596 - $revert = $this->skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Ipblocklist' ),
597 - wfMsg( 'unblocklink' ),
598 - 'action=unblock&ip=' . urlencode( $s->log_title ) );
599 - // show change protection link
600 - } elseif ( ( $s->log_action == 'protect' || $s->log_action == 'modify' ) && $wgUser->isAllowed( 'protect' ) ) {
601 - $revert = $this->skin->makeKnownLinkObj( $title, wfMsg( 'protect_change' ), 'action=unprotect' );
602 - // show user tool links for self created users
603 - // TODO: The extension should be handling this, get it out of core!
604 - } elseif ( $s->log_action == 'create2' ) {
605 - if( isset( $paramArray[0] ) ) {
606 - $revert = $this->skin->userToolLinks( $paramArray[0], $s->log_title, true );
607 - } else {
608 - # Fall back to a blue contributions link
609 - $revert = $this->skin->userToolLinks( 1, $s->log_title );
610 - }
611 - // If an edit was hidden from a page give a review link to the history
612 - } elseif ( $s->log_action == 'merge' ) {
613 - $merge = SpecialPage::getTitleFor( 'Mergehistory' );
614 - $revert = $this->skin->makeKnownLinkObj( $merge, wfMsg('revertmerge'),
615 - wfArrayToCGI( array('target' => $paramArray[0], 'dest' => $title->getPrefixedText() ) ) );
616 - // If an edit was hidden from a page give a review link to the history
617 - } else if( ($s->log_action=='revision') && $wgUser->isAllowed( 'deleterevision' ) ) {
618 - $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
619 - // Different revision types use different URL params...
620 - $subtype = isset($paramArray[2]) ? $paramArray[1] : '';
621 - // Link to each hidden object ID, $paramArray[1] is the url param.
622 - // Don't number by IDs because of their size.
623 - // We may often just have one, in which case it's easier to not...
624 - $Ids = explode( ',', $paramArray[2] );
625 - if( count($Ids) == 1 ) {
626 - $revert = $this->skin->makeKnownLinkObj( $revdel, wfMsgHtml('revdel-restore'),
627 - wfArrayToCGI( array('target' => $paramArray[0], $paramArray[1] => $Ids[0] ) ) );
628 - } else {
629 - $revert .= wfMsgHtml('revdel-restore').':';
630 - foreach( $Ids as $n => $id ) {
631 - $revert .= ' '.$this->skin->makeKnownLinkObj( $revdel, '#'.($n+1),
632 - wfArrayToCGI( array('target' => $paramArray[0], $paramArray[1] => $id ) ) );
 390+ // show unblock link
 391+ } elseif ( $s->log_action == 'block' && $wgUser->isAllowed( 'block' ) ) {
 392+ $revert = '(' . $skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Ipblocklist' ),
 393+ wfMsg( 'unblocklink' ),
 394+ 'action=unblock&ip=' . urlencode( $s->log_title ) ) . ')';
 395+ // show change protection link
 396+ } elseif ( ( $s->log_action == 'protect' || $s->log_action == 'modify' ) && $wgUser->isAllowed( 'protect' ) ) {
 397+ $revert = '(' . $skin->makeKnownLinkObj( $title, wfMsg( 'protect_change' ), 'action=unprotect' ) . ')';
 398+ // show user tool links for self created users
 399+ // TODO: The extension should be handling this, get it out of core!
 400+ } elseif ( $s->log_action == 'create2' ) {
 401+ if( isset( $paramArray[0] ) ) {
 402+ $revert = $this->skin->userToolLinks( $paramArray[0], $s->log_title, true );
 403+ } else {
 404+ # Fall back to a blue contributions link
 405+ $revert = $this->skin->userToolLinks( 1, $s->log_title );
633406 }
 407+ # Suppress $comment from old entries, not needed and can contain incorrect links
 408+ $comment = '';
634409 }
635 - // Hidden log items, give review link
636 - } else if( ($s->log_action=='event') && $wgUser->isAllowed( 'deleterevision' ) ) {
637 - $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
638 - $revert .= wfMsgHtml('revdel-restore');
639 - $Ids = explode( ',', $paramArray[0] );
640 - if( count($Ids) == 1 ) {
641 - $revert = $this->skin->makeKnownLinkObj( $revdel, wfMsgHtml('revdel-restore'),
642 - wfArrayToCGI( array('logid' => $Ids[0] ) ) );
643 - } else {
644 - foreach( $Ids as $n => $id ) {
645 - $revert .= $this->skin->makeKnownLinkObj( $revdel, '#'.($n+1),
646 - wfArrayToCGI( array('logid' => $id ) ) );
647 - }
648 - }
649410 }
650 - $revert = ($revert == '') ? "" : "&nbsp;&nbsp;&nbsp;($revert) ";
651 - return $revert;
 411+
 412+ $action = LogPage::actionText( $s->log_type, $s->log_action, $title, $this->skin, $paramArray, true );
 413+ $out = "<li>$time $userLink $action $comment $revert</li>\n";
 414+ return $out;
652415 }
653416
654417 /**
@@ -688,8 +451,6 @@
689452 * @private
690453 */
691454 function getTypeMenu() {
692 - global $wgLogRestrictions, $wgUser;
693 -
694455 $out = "<select name='type'>\n";
695456
696457 $validTypes = LogPage::validTypes();
@@ -707,14 +468,7 @@
708469 // Third pass generates sorted XHTML content
709470 foreach( $m as $text => $type ) {
710471 $selected = ($type == $this->reader->queryType());
711 - // Restricted types
712 - if ( isset($wgLogRestrictions[$type]) ) {
713 - if ( $wgUser->isAllowed( $wgLogRestrictions[$type] ) ) {
714 - $out .= Xml::option( $text, $type, $selected ) . "\n";
715 - }
716 - } else {
717 - $out .= Xml::option( $text, $type, $selected ) . "\n";
718 - }
 472+ $out .= Xml::option( $text, $type, $selected ) . "\n";
719473 }
720474
721475 $out .= '</select>';
@@ -770,41 +524,7 @@
771525 $this->numResults < $limit);
772526 $out->addHTML( '<p>' . $html . '</p>' );
773527 }
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 - }
801528 }
802529
803 -/**
804 - * Aliases for backwards compatibility with 1.6
805 - */
806 -define( 'MW_LOG_DELETED_ACTION', LogViewer::DELETED_ACTION );
807 -define( 'MW_LOG_DELETED_USER', LogViewer::DELETED_USER );
808 -define( 'MW_LOG_DELETED_COMMENT', LogViewer::DELETED_COMMENT );
809 -define( 'MW_LOG_DELETED_RESTRICTED', LogViewer::DELETED_RESTRICTED );
810530
811531
Index: trunk/phase3/includes/SpecialUndelete.php
@@ -78,7 +78,7 @@
7979 array(
8080 'ar_namespace',
8181 'ar_title',
82 - 'COUNT(*) AS count'
 82+ 'COUNT(*) AS count',
8383 ),
8484 $condition,
8585 __METHOD__,
@@ -92,6 +92,24 @@
9393 }
9494
9595 /**
 96+ * List the revisions of the given page. Returns result wrapper with
 97+ * (ar_minor_edit, ar_timestamp, ar_user, ar_user_text, ar_comment) fields.
 98+ *
 99+ * @return ResultWrapper
 100+ */
 101+ function listRevisions() {
 102+ $dbr = wfGetDB( DB_SLAVE );
 103+ $res = $dbr->select( 'archive',
 104+ array( 'ar_minor_edit', 'ar_timestamp', 'ar_user', 'ar_user_text', 'ar_comment', 'ar_len' ),
 105+ array( 'ar_namespace' => $this->title->getNamespace(),
 106+ 'ar_title' => $this->title->getDBkey() ),
 107+ 'PageArchive::listRevisions',
 108+ array( 'ORDER BY' => 'ar_timestamp DESC' ) );
 109+ $ret = $dbr->resultObject( $res );
 110+ return $ret;
 111+ }
 112+
 113+ /**
96114 * List the deleted file revisions for this page, if it's a file page.
97115 * Returns a result wrapper with various filearchive fields, or null
98116 * if not a file page.
@@ -106,22 +124,14 @@
107125 array(
108126 'fa_id',
109127 'fa_name',
110 - 'fa_archive_name',
111128 'fa_storage_key',
112 - 'fa_storage_group',
113129 'fa_size',
114130 'fa_width',
115131 'fa_height',
116 - 'fa_bits',
117 - 'fa_metadata',
118 - 'fa_media_type',
119 - 'fa_major_mime',
120 - 'fa_minor_mime',
121132 'fa_description',
122133 'fa_user',
123134 'fa_user_text',
124 - 'fa_timestamp',
125 - 'fa_deleted' ),
 135+ 'fa_timestamp' ),
126136 array( 'fa_name' => $this->title->getDbKey() ),
127137 __METHOD__,
128138 array( 'ORDER BY' => 'fa_timestamp DESC' ) );
@@ -142,25 +152,14 @@
143153 $rev = $this->getRevision( $timestamp );
144154 return $rev ? $rev->getText() : null;
145155 }
146 -
147 - function getRevisionConds( $timestamp, $id ) {
148 - if( $id ) {
149 - $id = intval($id);
150 - return "ar_rev_id=$id";
151 - } else if( $timestamp ) {
152 - return "ar_timestamp=$timestamp";
153 - } else {
154 - return 'ar_rev_id=0';
155 - }
156 - }
157156
158157 /**
159158 * Return a Revision object containing data for the deleted revision.
160 - * Note that the result *may* have a null page ID.
161 - * @param string $timestamp or $id
 159+ * Note that the result *may* or *may not* have a null page ID.
 160+ * @param string $timestamp
162161 * @return Revision
163162 */
164 - function getRevision( $timestamp, $id=null ) {
 163+ function getRevision( $timestamp ) {
165164 $dbr = wfGetDB( DB_SLAVE );
166165 $row = $dbr->selectRow( 'archive',
167166 array(
@@ -173,11 +172,10 @@
174173 'ar_minor_edit',
175174 'ar_flags',
176175 'ar_text_id',
177 - 'ar_deleted',
178176 'ar_len' ),
179177 array( 'ar_namespace' => $this->title->getNamespace(),
180178 'ar_title' => $this->title->getDbkey(),
181 - $this->getRevisionConds( $dbr->timestamp($timestamp), $id ) ),
 179+ 'ar_timestamp' => $dbr->timestamp( $timestamp ) ),
182180 __METHOD__ );
183181 if( $row ) {
184182 return new Revision( array(
@@ -191,9 +189,7 @@
192190 'user_text' => $row->ar_user_text,
193191 'timestamp' => $row->ar_timestamp,
194192 'minor_edit' => $row->ar_minor_edit,
195 - 'text_id' => $row->ar_text_id,
196 - 'deleted' => $row->ar_deleted,
197 - 'len' => $row->ar_len) );
 193+ 'text_id' => $row->ar_text_id ) );
198194 } else {
199195 return null;
200196 }
@@ -258,50 +254,48 @@
259255 * Restore the given (or all) text and file revisions for the page.
260256 * Once restored, the items will be removed from the archive tables.
261257 * The deletion log will be updated with an undeletion notice.
262 - * Use -1 for the one of the timestamps to only restore files or text
263258 *
264 - * @param string $pagetimestamp, restore all revisions since this time
 259+ * @param array $timestamps Pass an empty array to restore all revisions, otherwise list the ones to undelete.
265260 * @param string $comment
266 - * @param string $filetimestamp, restore all revision from this time on
267 - * @param bool $Unsuppress
 261+ * @param array $fileVersions
268262 *
269263 * @return true on success.
270264 */
271 - function undelete( $pagetimestamp = 0, $comment = '', $filetimestamp = 0, $Unsuppress = false) {
 265+ function undelete( $timestamps, $comment = '', $fileVersions = array() ) {
272266 // If both the set of text revisions and file revisions are empty,
273267 // restore everything. Otherwise, just restore the requested items.
274 - $restoreAll = ($pagetimestamp==0 && $filetimestamp==0);
 268+ $restoreAll = empty( $timestamps ) && empty( $fileVersions );
275269
276 - $restoreText = ($restoreAll || $pagetimestamp );
277 - $restoreFiles = ($restoreAll || $filetimestamp );
 270+ $restoreText = $restoreAll || !empty( $timestamps );
 271+ $restoreFiles = $restoreAll || !empty( $fileVersions );
278272
279 - if( $restoreText && $pagetimestamp >= 0 ) {
280 - $textRestored = $this->undeleteRevisions( $pagetimestamp, $Unsuppress );
281 - } else {
282 - $textRestored = 0;
283 - }
284 -
285 - if( $restoreFiles && $filetimestamp >= 0 && $this->title->getNamespace()==NS_IMAGE ) {
 273+ if( $restoreFiles && $this->title->getNamespace() == NS_IMAGE ) {
286274 $img = wfLocalFile( $this->title );
287 - $this->fileStatus = $img->restore( $filetimestamp, $Unsuppress );
 275+ $this->fileStatus = $img->restore( $fileVersions );
288276 $filesRestored = $this->fileStatus->successCount;
289277 } else {
290278 $filesRestored = 0;
291279 }
 280+
 281+ if( $restoreText ) {
 282+ $textRestored = $this->undeleteRevisions( $timestamps );
 283+ } else {
 284+ $textRestored = 0;
 285+ }
292286
293287 // Touch the log!
294288 global $wgContLang;
295289 $log = new LogPage( 'delete' );
296290
297291 if( $textRestored && $filesRestored ) {
298 - $reason = wfMsgExt( 'undeletedrevisions-files', array('parsemag'),
 292+ $reason = wfMsgForContent( 'undeletedrevisions-files',
299293 $wgContLang->formatNum( $textRestored ),
300294 $wgContLang->formatNum( $filesRestored ) );
301295 } elseif( $textRestored ) {
302 - $reason = wfMsgExt( 'undeletedrevisions', array('parsemag'),
 296+ $reason = wfMsgForContent( 'undeletedrevisions',
303297 $wgContLang->formatNum( $textRestored ) );
304298 } elseif( $filesRestored ) {
305 - $reason = wfMsgExt( 'undeletedfiles', array('parsemag'),
 299+ $reason = wfMsgForContent( 'undeletedfiles',
306300 $wgContLang->formatNum( $filesRestored ) );
307301 } else {
308302 wfDebug( "Undelete: nothing undeleted...\n" );
@@ -310,7 +304,7 @@
311305
312306 if( trim( $comment ) != '' )
313307 $reason .= ": {$comment}";
314 - $log->addEntry( 'restore', $this->title, $reason, array($pagetimestamp,$filetimestamp) );
 308+ $log->addEntry( 'restore', $this->title, $reason );
315309
316310 if ( $this->fileStatus && !$this->fileStatus->ok ) {
317311 return false;
@@ -324,73 +318,52 @@
325319 * to the cur/old tables. If the page currently exists, all revisions will
326320 * be stuffed into old, otherwise the most recent will go into cur.
327321 *
328 - * @param string $timestamps, restore all revisions since this time
 322+ * @param array $timestamps Pass an empty array to restore all revisions, otherwise list the ones to undelete.
329323 * @param string $comment
330324 * @param array $fileVersions
331 - * @param bool $Unsuppress, remove all ar_deleted/fa_deleted restrictions of seletected revs
332325 *
333326 * @return int number of revisions restored
334327 */
335 - private function undeleteRevisions( $timestamp, $Unsuppress = false ) {
336 - $restoreAll = ($timestamp==0);
 328+ private function undeleteRevisions( $timestamps ) {
 329+ $restoreAll = empty( $timestamps );
337330
338331 $dbw = wfGetDB( DB_MASTER );
339 - $makepage = false; // Do we need to make a new page?
340332
341333 # Does this page already exist? We'll have to update it...
342334 $article = new Article( $this->title );
343335 $options = 'FOR UPDATE';
344336 $page = $dbw->selectRow( 'page',
345337 array( 'page_id', 'page_latest' ),
346 - array( 'page_namespace' => $this->title->getNamespace(),
347 - 'page_title' => $this->title->getDBkey() ),
 338+ array( 'page_namespace' => $this->title->getNamespace(),
 339+ 'page_title' => $this->title->getDBkey() ),
348340 __METHOD__,
349341 $options );
350 -
351342 if( $page ) {
352343 # Page already exists. Import the history, and if necessary
353344 # we'll update the latest revision field in the record.
354345 $newid = 0;
355346 $pageId = $page->page_id;
356347 $previousRevId = $page->page_latest;
357 - # Get the time span of this page
358 - $previousTimestamp = $dbw->selectField( 'revision', 'rev_timestamp',
359 - array( 'rev_id' => $previousRevId ),
360 - __METHOD__ );
361 -
362 - if( $previousTimestamp === false ) {
363 - wfDebug( __METHOD__.": existing page refers to a page_latest that does not exist\n" );
364 - return false;
365 - }
366 - # Do not fuck up histories by merging them in annoying, unrevertable ways
367 - # This page id should match any deleted ones (excepting NULL values)
368 - # We can allow restoration into redirect pages with no edit history
369 - $otherpages = $dbw->selectField( 'archive', 'COUNT(*)',
370 - array( 'ar_namespace' => $this->title->getNamespace(),
371 - 'ar_title' => $this->title->getDBkey(),
372 - 'ar_page_id IS NOT NULL', "ar_page_id != $pageId" ),
373 - __METHOD__,
374 - array('LIMIT' => 1) );
375 - if( $otherpages && !$this->title->isValidRestoreOverTarget() ) {
376 - return false;
377 - }
378 -
379348 } else {
380349 # Have to create a new article...
381 - $makepage = true;
 350+ $newid = $article->insertOn( $dbw );
 351+ $pageId = $newid;
382352 $previousRevId = 0;
383 - $previousTimestamp = 0;
384353 }
385354
386 - $conditions = array(
387 - 'ar_namespace' => $this->title->getNamespace(),
388 - 'ar_title' => $this->title->getDBkey() );
389 - if( $timestamp ) {
390 - $conditions[] = "ar_timestamp >= {$timestamp}";
 355+ if( $restoreAll ) {
 356+ $oldones = '1 = 1'; # All revisions...
 357+ } else {
 358+ $oldts = implode( ',',
 359+ array_map( array( &$dbw, 'addQuotes' ),
 360+ array_map( array( &$dbw, 'timestamp' ),
 361+ $timestamps ) ) );
 362+
 363+ $oldones = "ar_timestamp IN ( {$oldts} )";
391364 }
392365
393366 /**
394 - * Select each archived revision...
 367+ * Restore each revision...
395368 */
396369 $result = $dbw->select( 'archive',
397370 /* fields */ array(
@@ -403,40 +376,24 @@
404377 'ar_minor_edit',
405378 'ar_flags',
406379 'ar_text_id',
407 - 'ar_deleted',
408380 'ar_len' ),
409 - /* WHERE */
410 - $conditions,
 381+ /* WHERE */ array(
 382+ 'ar_namespace' => $this->title->getNamespace(),
 383+ 'ar_title' => $this->title->getDBkey(),
 384+ $oldones ),
411385 __METHOD__,
412386 /* options */ array(
413387 'ORDER BY' => 'ar_timestamp' )
414388 );
415 - $ret = $dbw->resultObject( $result );
416 -
417 - $rev_count = $dbw->numRows( $result );
418 - if( $rev_count ) {
419 - # We need to seek around as just using DESC in the ORDER BY
420 - # would leave the revisions inserted in the wrong order
421 - $first = $ret->fetchObject();
422 - $ret->seek( $rev_count - 1 );
423 - $last = $ret->fetchObject();
424 - // We don't handle well changing the top revision's settings
425 - if( !$Unsuppress && $last->ar_deleted && $last->ar_timestamp > $previousTimestamp ) {
426 - wfDebug( __METHOD__.": restoration would result in a deleted top revision\n" );
427 - return false;
428 - }
429 - $ret->seek( 0 );
 389+ if( $dbw->numRows( $result ) < count( $timestamps ) ) {
 390+ wfDebug( __METHOD__.": couldn't find all requested rows\n" );
 391+ return false;
430392 }
431393
432 - if( $makepage ) {
433 - $newid = $article->insertOn( $dbw );
434 - $pageId = $newid;
435 - }
436 -
437394 $revision = null;
438395 $restored = 0;
439 -
440 - while( $row = $ret->fetchObject() ) {
 396+
 397+ while( $row = $dbw->fetchObject( $result ) ) {
441398 if( $row->ar_text_id ) {
442399 // Revision was deleted in 1.5+; text is in
443400 // the regular text table, use the reference.
@@ -459,14 +416,12 @@
460417 'timestamp' => $row->ar_timestamp,
461418 'minor_edit' => $row->ar_minor_edit,
462419 'text_id' => $row->ar_text_id,
463 - 'deleted' => $Unsuppress ? 0 : $row->ar_deleted,
464 - 'len' => $row->ar_len
 420+ 'len' => $row->ar_len
465421 ) );
466422 $revision->insertOn( $dbw );
467423 $restored++;
468424 }
469 -
470 - # If there were any revisions restored...
 425+
471426 if( $revision ) {
472427 // Attach the latest revision to the page...
473428 $wasnew = $article->updateIfNewerOn( $dbw, $revision, $previousRevId );
@@ -475,7 +430,7 @@
476431 // Update site stats, link tables, etc
477432 $article->createUpdates( $revision );
478433 }
479 -
 434+
480435 if( $newid ) {
481436 wfRunHooks( 'ArticleUndelete', array( &$this->title, true ) );
482437 Article::onArticleCreate( $this->title );
@@ -483,22 +438,17 @@
484439 wfRunHooks( 'ArticleUndelete', array( &$this->title, false ) );
485440 Article::onArticleEdit( $this->title );
486441 }
 442+ } else {
 443+ # Something went terribly wrong!
487444 }
488445
489446 # Now that it's safely stored, take it out of the archive
490447 $dbw->delete( 'archive',
491 - /* WHERE */
492 - $conditions,
 448+ /* WHERE */ array(
 449+ 'ar_namespace' => $this->title->getNamespace(),
 450+ 'ar_title' => $this->title->getDBkey(),
 451+ $oldones ),
493452 __METHOD__ );
494 - # Update any revision left to reflect the page they belong to.
495 - # If a page was deleted, and a new one created over it, then deleted,
496 - # selective restore acts as a way to seperate the two. Nevertheless, we
497 - # still want the rest to be restorable, in case some mistake was made.
498 - $dbw->update( 'archive',
499 - array( 'ar_page_id' => $newid ),
500 - array( 'ar_namespace' => $this->title->getNamespace(),
501 - 'ar_title' => $this->title->getDBkey() ),
502 - __METHOD__ );
503453
504454 return $restored;
505455 }
@@ -523,92 +473,71 @@
524474 $time = $request->getVal( 'timestamp' );
525475 $this->mTimestamp = $time ? wfTimestamp( TS_MW, $time ) : '';
526476 $this->mFile = $request->getVal( 'file' );
527 - $this->mDiff = $request->getVal( 'diff' );
528 - $this->mOldid = $request->getVal( 'oldid' );
529477
530 - $posted = $request->wasPosted() && $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) );
 478+ $posted = $request->wasPosted() &&
 479+ $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) );
531480 $this->mRestore = $request->getCheck( 'restore' ) && $posted;
532481 $this->mPreview = $request->getCheck( 'preview' ) && $posted;
533482 $this->mComment = $request->getText( 'wpComment' );
534 - $this->mUnsuppress = $request->getVal( 'wpUnsuppress' ) && $wgUser->isAllowed( 'oversight' );
535483
536484 if( $par != "" ) {
537485 $this->mTarget = $par;
538 - $_GET['target'] = $par; // hack for Pager
539486 }
540 - if( $wgUser->isAllowed( 'delete' ) && !$wgUser->isBlocked() ) {
 487+ if ( $wgUser->isAllowed( 'delete' ) && !$wgUser->isBlocked() ) {
541488 $this->mAllowed = true;
542489 } else {
543490 $this->mAllowed = false;
544491 $this->mTimestamp = '';
545492 $this->mRestore = false;
546493 }
547 - if( $this->mTarget !== "" ) {
 494+ if ( $this->mTarget !== "" ) {
548495 $this->mTargetObj = Title::newFromURL( $this->mTarget );
549496 } else {
550497 $this->mTargetObj = NULL;
551498 }
552499 if( $this->mRestore ) {
553 - $this->mFileTimestamp = $request->getVal('imgrestorepoint');
554 - $this->mPageTimestamp = $request->getVal('restorepoint');
555 - }
556 - $this->preCacheMessages();
557 - }
558 -
559 - /**
560 - * As we use the same small set of messages in various methods and that
561 - * they are called often, we call them once and save them in $this->message
562 - */
563 - function preCacheMessages() {
564 - // Precache various messages
565 - if( !isset( $this->message ) ) {
566 - foreach( explode(' ', 'last rev-delundel' ) as $msg ) {
567 - $this->message[$msg] = wfMsgExt( $msg, array( 'escape') );
 500+ $timestamps = array();
 501+ $this->mFileVersions = array();
 502+ foreach( $_REQUEST as $key => $val ) {
 503+ $matches = array();
 504+ if( preg_match( '/^ts(\d{14})$/', $key, $matches ) ) {
 505+ array_push( $timestamps, $matches[1] );
 506+ }
 507+
 508+ if( preg_match( '/^fileid(\d+)$/', $key, $matches ) ) {
 509+ $this->mFileVersions[] = intval( $matches[1] );
 510+ }
568511 }
 512+ rsort( $timestamps );
 513+ $this->mTargetTimestamp = $timestamps;
569514 }
570515 }
571516
572517 function execute() {
573 - global $wgOut, $wgUser;
574 - if( $this->mAllowed ) {
575 - $wgOut->setPagetitle( wfMsgHtml( "undeletepage" ) );
 518+ global $wgOut;
 519+ if ( $this->mAllowed ) {
 520+ $wgOut->setPagetitle( wfMsg( "undeletepage" ) );
576521 } else {
577 - $wgOut->setPagetitle( wfMsgHtml( "viewdeletedpage" ) );
 522+ $wgOut->setPagetitle( wfMsg( "viewdeletedpage" ) );
578523 }
579524
580525 if( is_null( $this->mTargetObj ) ) {
581 - # Not all users can just browse every deleted page from the list
582 - if( $wgUser->isAllowed( 'browsearchive' ) ) {
583 - $this->showSearchForm();
 526+ $this->showSearchForm();
584527
585 - # List undeletable articles
586 - if( $this->mSearchPrefix ) {
587 - $result = PageArchive::listPagesByPrefix( $this->mSearchPrefix );
588 - $this->showList( $result );
589 - }
590 - } else {
591 - $wgOut->addWikiText( wfMsgHtml( 'undelete-header' ) );
 528+ # List undeletable articles
 529+ if( $this->mSearchPrefix ) {
 530+ $result = PageArchive::listPagesByPrefix(
 531+ $this->mSearchPrefix );
 532+ $this->showList( $result );
592533 }
593534 return;
594535 }
595536 if( $this->mTimestamp !== '' ) {
596537 return $this->showRevision( $this->mTimestamp );
597538 }
598 -
599 - if( $this->mDiff && $this->mOldid )
600 - return $this->showDiff( $this->mDiff, $this->mOldid );
601 -
602539 if( $this->mFile !== null ) {
603 - $file = new ArchivedFile( $this->mTargetObj, '', $this->mFile );
604 - // Check if user is allowed to see this file
605 - if( !$file->userCan( File::DELETED_FILE ) ) {
606 - $wgOut->permissionRequired( 'hiderevision' );
607 - return false;
608 - } else {
609 - return $this->showFile( $this->mFile );
610 - }
 540+ return $this->showFile( $this->mFile );
611541 }
612 -
613542 if( $this->mRestore && $this->mAction == "submit" ) {
614543 return $this->undelete();
615544 }
@@ -636,8 +565,7 @@
637566 '</form>' );
638567 }
639568
640 - // Generic list of deleted pages
641 - private function showList( $result ) {
 569+ /* private */ function showList( $result ) {
642570 global $wgLang, $wgContLang, $wgUser, $wgOut;
643571
644572 if( $result->numRows() == 0 ) {
@@ -665,7 +593,7 @@
666594 return true;
667595 }
668596
669 - private function showRevision( $timestamp ) {
 597+ /* private */ function showRevision( $timestamp ) {
670598 global $wgLang, $wgUser, $wgOut;
671599 $self = SpecialPage::getTitleFor( 'Undelete' );
672600 $skin = $wgUser->getSkin();
@@ -676,24 +604,14 @@
677605 $rev = $archive->getRevision( $timestamp );
678606
679607 if( !$rev ) {
680 - $wgOut->addWikiText( wfMsg( 'undeleterevision-missing' ) );
 608+ $wgOut->addWikiTexT( wfMsg( 'undeleterevision-missing' ) );
681609 return;
682610 }
683611
684 - if( $rev->isDeleted(Revision::DELETED_TEXT) ) {
685 - if( !$rev->userCan(Revision::DELETED_TEXT) ) {
686 - $wgOut->addWikiText( wfMsg( 'rev-deleted-text-permission' ) );
687 - return;
688 - } else {
689 - $wgOut->addWikiText( wfMsg( 'rev-deleted-text-view' ) );
690 - $wgOut->addHTML( '<br/>' );
691 - // and we are allowed to see...
692 - }
693 - }
694 -
695612 $wgOut->setPageTitle( wfMsg( 'undeletepage' ) );
696613
697 - $link = $skin->makeKnownLinkObj( $self,
 614+ $link = $skin->makeKnownLinkObj(
 615+ $self,
698616 htmlspecialchars( $this->mTargetObj->getPrefixedText() ),
699617 'target=' . $this->mTargetObj->getPrefixedUrl()
700618 );
@@ -707,7 +625,7 @@
708626
709627 if( $this->mPreview ) {
710628 $wgOut->addHtml( "<hr />\n" );
711 - $wgOut->addWikiTextTitleTidy( $rev->revText(), $this->mTargetObj, false );
 629+ $wgOut->addWikiTextTitleTidy( $rev->getText(), $this->mTargetObj, false );
712630 }
713631
714632 $wgOut->addHtml(
@@ -715,7 +633,7 @@
716634 'readonly' => 'readonly',
717635 'cols' => intval( $wgUser->getOption( 'cols' ) ),
718636 'rows' => intval( $wgUser->getOption( 'rows' ) ) ),
719 - $rev->revText() . "\n" ) .
 637+ $rev->getText() . "\n" ) .
720638 wfOpenElement( 'div' ) .
721639 wfOpenElement( 'form', array(
722640 'method' => 'post',
@@ -742,74 +660,11 @@
743661 wfCloseElement( 'form' ) .
744662 wfCloseElement( 'div' ) );
745663 }
746 -
747 - /**
748 - * Show the changes between two deleted revisions
749 - */
750 - private function showDiff( $newid, $oldid ) {
751 - global $wgOut, $wgUser, $wgLang;
752664
753 - if( is_null($this->mTargetObj) )
754 - return;
755 - $skin = $wgUser->getSkin();
756 -
757 - $archive = new PageArchive( $this->mTargetObj );
758 - $oldRev = $archive->getRevision( null, $oldid );
759 - $newRev = $archive->getRevision( null, $newid );
760 -
761 - if( !$oldRev || !$newRev )
762 - return;
763 -
764 - $oldTitle = $this->mTargetObj->getPrefixedText();
765 - $wgOut->addHtml( "<center><h3>$oldTitle</h3></center>" );
766 -
767 - $oldminor = $newminor = '';
768 -
769 - if($oldRev->mMinorEdit == 1) {
770 - $oldminor = wfElement( 'span', array( 'class' => 'minor' ),
771 - wfMsg( 'minoreditletter') ) . ' ';
772 - }
773 -
774 - if($newRev->mMinorEdit == 1) {
775 - $newminor = wfElement( 'span', array( 'class' => 'minor' ),
776 - wfMsg( 'minoreditletter') ) . ' ';
777 - }
778 -
779 - $ot = $wgLang->timeanddate( $oldRev->getTimestamp(), true );
780 - $nt = $wgLang->timeanddate( $newRev->getTimestamp(), true );
781 - $oldHeader = htmlspecialchars( wfMsg( 'revisionasof', $ot ) ) . "<br />" .
782 - $skin->revUserTools( $oldRev, true ) . "<br />" .
783 - $oldminor . $skin->revComment( $oldRev, false ) . "<br />";
784 - $newHeader = htmlspecialchars( wfMsg( 'revisionasof', $nt ) ) . "<br />" .
785 - $skin->revUserTools( $newRev, true ) . " <br />" .
786 - $newminor . $skin->revComment( $newRev, false ) . "<br />";
787 -
788 - $otext = $oldRev->revText();
789 - $ntext = $newRev->revText();
790 -
791 - $wgOut->addStyle( 'common/diff.css' );
792 - $wgOut->addHtml(
793 - "<div>" .
794 - "<table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>" .
795 - "<col class='diff-marker' />" .
796 - "<col class='diff-content' />" .
797 - "<col class='diff-marker' />" .
798 - "<col class='diff-content' />" .
799 - "<tr>" .
800 - "<td colspan='2' width='50%' align='center' class='diff-otitle'>" . $oldHeader . "</td>" .
801 - "<td colspan='2' width='50%' align='center' class='diff-ntitle'>" . $newHeader . "</td>" .
802 - "</tr>" .
803 - DifferenceEngine::generateDiffBody( $otext, $ntext ) .
804 - "</table>" .
805 - "</div>\n" );
806 -
807 - return true;
808 - }
809 -
810665 /**
811666 * Show a deleted file version requested by the visitor.
812667 */
813 - private function showFile( $key ) {
 668+ function showFile( $key ) {
814669 global $wgOut, $wgRequest;
815670 $wgOut->disable();
816671
@@ -825,35 +680,47 @@
826681 $store->stream( $key );
827682 }
828683
829 - private function showHistory() {
 684+ /* private */ function showHistory() {
830685 global $wgLang, $wgContLang, $wgUser, $wgOut;
831686
832 - $this->sk = $wgUser->getSkin();
833 - if( $this->mAllowed ) {
 687+ $sk = $wgUser->getSkin();
 688+ if ( $this->mAllowed ) {
834689 $wgOut->setPagetitle( wfMsg( "undeletepage" ) );
835690 } else {
836691 $wgOut->setPagetitle( wfMsg( 'viewdeletedpage' ) );
837692 }
838 -
839 - $wgOut->addWikiText( wfMsgHtml( 'undeletepagetitle', $this->mTargetObj->getPrefixedText()) );
840693
841694 $archive = new PageArchive( $this->mTargetObj );
842 -
843 - if( $this->mAllowed ) {
844 - $wgOut->addWikiText( '<p>' . wfMsgHtml( "undeletehistory" ) . '</p>' );
845 - $wgOut->addHtml( '<p>' . wfMsgHtml( "undeleterevdel" ) . '</p>' );
 695+ /*
 696+ $text = $archive->getLastRevisionText();
 697+ if( is_null( $text ) ) {
 698+ $wgOut->addWikiText( wfMsg( "nohistory" ) );
 699+ return;
 700+ }
 701+ */
 702+ if ( $this->mAllowed ) {
 703+ $wgOut->addWikiText( wfMsg( "undeletehistory" ) );
846704 } else {
847 - $wgOut->addWikiText( wfMsgHtml( "undeletehistorynoadmin" ) );
 705+ $wgOut->addWikiText( wfMsg( "undeletehistorynoadmin" ) );
848706 }
849707
850708 # List all stored revisions
851 - $revisions = new UndeleteRevisionsPager( $this, array(), $this->mTargetObj );
 709+ $revisions = $archive->listRevisions();
852710 $files = $archive->listFiles();
853711
854 - $haveRevisions = $revisions && $revisions->getNumRows() > 0;
 712+ $haveRevisions = $revisions && $revisions->numRows() > 0;
855713 $haveFiles = $files && $files->numRows() > 0;
856714
857715 # Batch existence check on user and talk pages
 716+ if( $haveRevisions ) {
 717+ $batch = new LinkBatch();
 718+ while( $row = $revisions->fetchObject() ) {
 719+ $batch->addObj( Title::makeTitleSafe( NS_USER, $row->ar_user_text ) );
 720+ $batch->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->ar_user_text ) );
 721+ }
 722+ $batch->execute();
 723+ $revisions->seek( 0 );
 724+ }
858725 if( $haveFiles ) {
859726 $batch = new LinkBatch();
860727 while( $row = $files->fetchObject() ) {
@@ -864,7 +731,7 @@
865732 $files->seek( 0 );
866733 }
867734
868 - if( $this->mAllowed ) {
 735+ if ( $this->mAllowed ) {
869736 $titleObj = SpecialPage::getTitleFor( "Undelete" );
870737 $action = $titleObj->getLocalURL( "action=submit" );
871738 # Start the form here
@@ -872,6 +739,20 @@
873740 $wgOut->addHtml( $top );
874741 }
875742
 743+ # Show relevant lines from the deletion log:
 744+ $wgOut->addHTML( "<h2>" . htmlspecialchars( LogPage::logName( 'delete' ) ) . "</h2>\n" );
 745+ $logViewer = new LogViewer(
 746+ new LogReader(
 747+ new FauxRequest(
 748+ array(
 749+ 'page' => $this->mTargetObj->getPrefixedText(),
 750+ 'type' => 'delete'
 751+ )
 752+ )
 753+ ), LogViewer::NO_ACTION_LINK
 754+ );
 755+ $logViewer->showList( $wgOut );
 756+
876757 if( $this->mAllowed && ( $haveRevisions || $haveFiles ) ) {
877758 # Format the user-visible controls (comment field, submission button)
878759 # in a nice little table
@@ -897,10 +778,6 @@
898779 <td>" .
899780 Xml::submitButton( wfMsg( 'undeletebtn' ), array( 'name' => 'restore', 'id' => 'mw-undelete-submit' ) ) .
900781 Xml::element( 'input', array( 'type' => 'reset', 'value' => wfMsg( 'undeletereset' ), 'id' => 'mw-undelete-reset' ) ) .
901 - Xml::openElement( 'p' ) .
902 - Xml::check( 'wpUnsuppress', $this->mUnsuppress, array('id' => 'mw-undelete-unsupress') ) . ' ' .
903 - Xml::label( wfMsgHtml('revdelete-unsuppress'), 'mw-undelete-unsupress' ) .
904 - Xml::closeElement( 'p' ) .
905782 "</td>
906783 </tr>" .
907784 Xml::closeElement( 'table' ) .
@@ -909,38 +786,59 @@
910787 $wgOut->addHtml( $table );
911788 }
912789
913 - $wgOut->addHTML( "<h2 id=\"pagehistory\">" . wfMsgHtml( "history" ) . "</h2>\n" );
 790+ $wgOut->addHTML( "<h2>" . htmlspecialchars( wfMsg( "history" ) ) . "</h2>\n" );
914791
915792 if( $haveRevisions ) {
916 - $wgOut->addHTML( '<p>' . wfMsgHtml( "restorepoint" ) . '</p>' );
917 - $wgOut->addHTML( $revisions->getNavigationBar() );
918 - $wgOut->addHTML( "<ul>" );
919 - $wgOut->addHTML( "<li>" . wfRadio( "restorepoint", -1, false ) . " " . wfMsgHtml('restorenone') . "</li>" );
920 - $wgOut->addHTML( $revisions->getBody() );
921 - $wgOut->addHTML( "</ul>" );
922 - $wgOut->addHTML( $revisions->getNavigationBar() );
 793+ # The page's stored (deleted) history:
 794+ $wgOut->addHTML("<ul>");
 795+ $target = urlencode( $this->mTarget );
 796+ while( $row = $revisions->fetchObject() ) {
 797+ $ts = wfTimestamp( TS_MW, $row->ar_timestamp );
 798+ if ( $this->mAllowed ) {
 799+ $checkBox = Xml::check( "ts$ts" );
 800+ $pageLink = $sk->makeKnownLinkObj( $titleObj,
 801+ $wgLang->timeanddate( $ts, true ),
 802+ "target=$target&timestamp=$ts" );
 803+ } else {
 804+ $checkBox = '';
 805+ $pageLink = $wgLang->timeanddate( $ts, true );
 806+ }
 807+ $userLink = $sk->userLink( $row->ar_user, $row->ar_user_text ) . $sk->userToolLinks( $row->ar_user, $row->ar_user_text );
 808+ $stxt = '';
 809+ if (!is_null($size = $row->ar_len)) {
 810+ if ($size == 0) {
 811+ $stxt = wfMsgHtml('historyempty');
 812+ } else {
 813+ $stxt = wfMsgHtml('historysize', $wgLang->formatNum( $size ) );
 814+ }
 815+ }
 816+ $comment = $sk->commentBlock( $row->ar_comment );
 817+ $wgOut->addHTML( "<li>$checkBox $pageLink . . $userLink $stxt $comment</li>\n" );
 818+
 819+ }
 820+ $revisions->free();
 821+ $wgOut->addHTML("</ul>");
923822 } else {
924823 $wgOut->addWikiText( wfMsg( "nohistory" ) );
925824 }
 825+
926826 if( $haveFiles ) {
927 - $wgOut->addHtml( "<h2 id=\"filehistory\">" . wfMsgHtml( 'filehist' ) . "</h2>\n" );
928 - $wgOut->addHTML( wfMsgHtml( "restorepoint" ) );
 827+ $wgOut->addHtml( "<h2>" . wfMsgHtml( 'filehist' ) . "</h2>\n" );
929828 $wgOut->addHtml( "<ul>" );
930 - $wgOut->addHTML( "<li>" . wfRadio( "imgrestorepoint", -1, false ) . " " . wfMsgHtml('restorenone') . "</li>" );
931829 while( $row = $files->fetchObject() ) {
932 - $file = ArchivedFile::newFromRow( $row );
933 -
934830 $ts = wfTimestamp( TS_MW, $row->fa_timestamp );
935 - if( $this->mAllowed && $row->fa_storage_key ) {
936 - $checkBox = wfRadio( "imgrestorepoint", $ts, false );
 831+ if ( $this->mAllowed && $row->fa_storage_key ) {
 832+ $checkBox = Xml::check( "fileid" . $row->fa_id );
937833 $key = urlencode( $row->fa_storage_key );
938834 $target = urlencode( $this->mTarget );
939 - $pageLink = $this->getFileLink( $file, $titleObj, $ts, $target, $key );
 835+ $pageLink = $sk->makeKnownLinkObj( $titleObj,
 836+ $wgLang->timeanddate( $ts, true ),
 837+ "target=$target&file=$key" );
940838 } else {
941839 $checkBox = '';
942840 $pageLink = $wgLang->timeanddate( $ts, true );
943841 }
944 - $userLink = $this->getFileUser( $file );
 842+ $userLink = $sk->userLink( $row->fa_user, $row->fa_user_text ) . $sk->userToolLinks( $row->fa_user, $row->fa_user_text );
945843 $data =
946844 wfMsgHtml( 'widthheight',
947845 $wgLang->formatNum( $row->fa_width ),
@@ -948,40 +846,14 @@
949847 ' (' .
950848 wfMsgHtml( 'nbytes', $wgLang->formatNum( $row->fa_size ) ) .
951849 ')';
952 - $comment = $this->getFileComment( $file );
953 - $rd='';
954 - if( $wgUser->isAllowed( 'deleterevision' ) ) {
955 - $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
956 - if( !$file->userCan(File::DELETED_RESTRICTED ) ) {
957 - // If revision was hidden from sysops
958 - $del = $this->message['rev-delundel'];
959 - } else {
960 - $del = $this->sk->makeKnownLinkObj( $revdel,
961 - $this->message['rev-delundel'],
962 - 'target=' . urlencode( $this->mTarget ) .
963 - '&fileid=' . urlencode( $row->fa_id ) );
964 - // Bolden oversighted content
965 - if( $file->isDeleted( File::DELETED_RESTRICTED ) )
966 - $del = "<strong>$del</strong>";
967 - }
968 - $rd = "<tt>(<small>$del</small>)</tt>";
969 - }
970 - $wgOut->addHTML( "<li>$checkBox $rd $pageLink . . $userLink $data $comment</li>\n" );
 850+ $comment = $sk->commentBlock( $row->fa_description );
 851+ $wgOut->addHTML( "<li>$checkBox $pageLink . . $userLink $data $comment</li>\n" );
971852 }
972853 $files->free();
973854 $wgOut->addHTML( "</ul>" );
974855 }
975856
976 - # Show relevant lines from the deletion log:
977 - $wgOut->addHTML( "<h2>" . htmlspecialchars( LogPage::logName( 'delete' ) ) . "</h2>\n" );
978 - $logViewer = new LogViewer(
979 - new LogReader(
980 - new FauxRequest(
981 - array( 'page' => $this->mTargetObj->getPrefixedText(),
982 - 'type' => 'delete' ) ) ) );
983 - $logViewer->showList( $wgOut );
984 -
985 - if( $this->mAllowed ) {
 857+ if ( $this->mAllowed ) {
986858 # Slip in the hidden controls here
987859 $misc = Xml::hidden( 'target', $this->mTarget );
988860 $misc .= Xml::hidden( 'wpEditToken', $wgUser->editToken() );
@@ -991,152 +863,23 @@
992864
993865 return true;
994866 }
995 -
996 - function formatRevisionRow( $row ) {
997 - global $wgUser, $wgLang;
998 -
999 - $rev = new Revision( array(
1000 - 'page' => $this->mTargetObj->getArticleId(),
1001 - 'id' => $row->ar_rev_id,
1002 - 'comment' => $row->ar_comment,
1003 - 'user' => $row->ar_user,
1004 - 'user_text' => $row->ar_user_text,
1005 - 'timestamp' => $row->ar_timestamp,
1006 - 'minor_edit' => $row->ar_minor_edit,
1007 - 'text_id' => $row->ar_text_id,
1008 - 'deleted' => $row->ar_deleted,
1009 - 'len' => $row->ar_len) );
1010 -
1011 - $stxt = '';
1012 - $last = $this->message['last'];
1013 -
1014 - if( $this->mAllowed ) {
1015 - $ts = wfTimestamp( TS_MW, $row->ar_timestamp );
1016 - $checkBox = wfRadio( "restorepoint", $ts, false );
1017 - $titleObj = SpecialPage::getTitleFor( "Undelete" );
1018 - $pageLink = $this->getPageLink( $rev, $titleObj, $ts, $this->mTarget );
1019 - # Last link
1020 - if( !$rev->userCan( Revision::DELETED_TEXT ) )
1021 - $last = $this->message['last'];
1022 - else if( isset($this->prevId[$row->ar_rev_id]) )
1023 - $last = $this->sk->makeKnownLinkObj( $titleObj, $this->message['last'], "target=" . $this->mTarget .
1024 - "&diff=" . $row->ar_rev_id . "&oldid=" . $this->prevId[$row->ar_rev_id] );
1025 - } else {
1026 - $checkBox = '';
1027 - $pageLink = $wgLang->timeanddate( $ts, true );
1028 - }
1029 - $userLink = $this->sk->revUserTools( $rev );
1030 -
1031 - if(!is_null($size = $row->ar_len)) {
1032 - if($size == 0)
1033 - $stxt = wfMsgHtml('historyempty');
1034 - else
1035 - $stxt = wfMsgHtml('historysize', $wgLang->formatNum( $size ) );
1036 - }
1037 - $comment = $this->sk->revComment( $rev );
1038 - $revd='';
1039 - if( $wgUser->isAllowed( 'deleterevision' ) ) {
1040 - $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
1041 - if( !$rev->userCan( Revision::DELETED_RESTRICTED ) ) {
1042 - // If revision was hidden from sysops
1043 - $del = $this->message['rev-delundel'];
1044 - } else {
1045 - $del = $this->sk->makeKnownLinkObj( $revdel,
1046 - $this->message['rev-delundel'],
1047 - 'target=' . urlencode( $this->mTarget ) .
1048 - '&artimestamp=' . urlencode( $row->ar_timestamp ) );
1049 - // Bolden oversighted content
1050 - if( $rev->isDeleted( Revision::DELETED_RESTRICTED ) )
1051 - $del = "<strong>$del</strong>";
1052 - }
1053 - $revd = "<tt>(<small>$del</small>)</tt>";
1054 - }
1055 -
1056 - return "<li>$checkBox $revd ($last) $pageLink . . $userLink $stxt $comment</li>";
1057 - }
1058867
1059 - /**
1060 - * Fetch revision text link if it's available to all users
1061 - * @return string
1062 - */
1063 - function getPageLink( $rev, $titleObj, $ts, $target ) {
1064 - global $wgLang;
1065 -
1066 - if( !$rev->userCan(Revision::DELETED_TEXT) ) {
1067 - return '<span class="history-deleted">' . $wgLang->timeanddate( $ts, true ) . '</span>';
1068 - } else {
1069 - $link = $this->sk->makeKnownLinkObj( $titleObj, $wgLang->timeanddate( $ts, true ), "target=$target&timestamp=$ts" );
1070 - if( $rev->isDeleted(Revision::DELETED_TEXT) )
1071 - $link = '<span class="history-deleted">' . $link . '</span>';
1072 - return $link;
1073 - }
1074 - }
1075 -
1076 - /**
1077 - * Fetch image view link if it's available to all users
1078 - * @return string
1079 - */
1080 - function getFileLink( $file, $titleObj, $ts, $target, $key ) {
1081 - global $wgLang;
1082 -
1083 - if( !$file->userCan(File::DELETED_FILE) ) {
1084 - return '<span class="history-deleted">' . $wgLang->timeanddate( $ts, true ) . '</span>';
1085 - } else {
1086 - $link = $this->sk->makeKnownLinkObj( $titleObj, $wgLang->timeanddate( $ts, true ), "target=$target&file=$key" );
1087 - if( $file->isDeleted(File::DELETED_FILE) )
1088 - $link = '<span class="history-deleted">' . $link . '</span>';
1089 - return $link;
1090 - }
1091 - }
1092 -
1093 - /**
1094 - * Fetch file's user id if it's available to this user
1095 - * @return string
1096 - */
1097 - function getFileUser( $file ) {
1098 - if( !$file->userCan(File::DELETED_USER) ) {
1099 - return '<span class="history-deleted">' . wfMsgHtml( 'rev-deleted-user' ) . '</span>';
1100 - } else {
1101 - $link = $this->sk->userLink( $file->user, $file->userText ) .
1102 - $this->sk->userToolLinks( $file->user, $file->userText );
1103 - if( $file->isDeleted(File::DELETED_USER) )
1104 - $link = '<span class="history-deleted">' . $link . '</span>';
1105 - return $link;
1106 - }
1107 - }
1108 -
1109 - /**
1110 - * Fetch file upload comment if it's available to this user
1111 - * @return string
1112 - */
1113 - function getFileComment( $file ) {
1114 - if( !$file->userCan(File::DELETED_COMMENT) ) {
1115 - return '<span class="history-deleted"><span class="comment">' . wfMsgHtml( 'rev-deleted-comment' ) . '</span></span>';
1116 - } else {
1117 - $link = $this->sk->commentBlock( $file->description );
1118 - if( $file->isDeleted(File::DELETED_COMMENT) )
1119 - $link = '<span class="history-deleted">' . $link . '</span>';
1120 - return $link;
1121 - }
1122 - }
1123 -
1124868 function undelete() {
1125869 global $wgOut, $wgUser;
1126870 if( !is_null( $this->mTargetObj ) ) {
1127871 $archive = new PageArchive( $this->mTargetObj );
1128872
1129873 $ok = $archive->undelete(
1130 - $this->mPageTimestamp,
 874+ $this->mTargetTimestamp,
1131875 $this->mComment,
1132 - $this->mFileTimestamp,
1133 - $this->mUnsuppress );
 876+ $this->mFileVersions );
 877+
1134878 if( $ok ) {
1135879 $skin = $wgUser->getSkin();
1136 - $link = $skin->makeKnownLinkObj( $this->mTargetObj, $this->mTargetObj->getPrefixedText(), 'redirect=no' );
 880+ $link = $skin->makeKnownLinkObj( $this->mTargetObj );
1137881 $wgOut->addHtml( wfMsgWikiHtml( 'undeletedpage', $link ) );
1138882 } else {
1139883 $wgOut->showFatalError( wfMsg( "cannotundelete" ) );
1140 - $wgOut->addHtml( '<p>' . wfMsgHtml( "undeleterevdel" ) . '</p>' );
1141884 }
1142885
1143886 // Show file deletion warnings and errors
@@ -1151,61 +894,4 @@
1152895 }
1153896 }
1154897
1155 -class UndeleteRevisionsPager extends ReverseChronologicalPager {
1156 - public $mForm, $mConds;
1157898
1158 - function __construct( $form, $conds = array(), $title ) {
1159 - $this->mForm = $form;
1160 - $this->mConds = $conds;
1161 - $this->title = $title;
1162 - parent::__construct();
1163 - }
1164 -
1165 - function getStartBody() {
1166 - wfProfileIn( __METHOD__ );
1167 - # Do a link batch query
1168 - $this->mResult->seek( 0 );
1169 - $batch = new LinkBatch();
1170 - # Give some pointers to make (last) links
1171 - $this->mForm->prevId = array();
1172 - while( $row = $this->mResult->fetchObject() ) {
1173 - $batch->addObj( Title::makeTitleSafe( NS_USER, $row->ar_user_text ) );
1174 - $batch->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->ar_user_text ) );
1175 -
1176 - $rev_id = isset($rev_id) ? $rev_id : $row->ar_rev_id;
1177 - if( $rev_id > $row->ar_rev_id )
1178 - $this->mForm->prevId[$rev_id] = $row->ar_rev_id;
1179 - else if( $rev_id < $row->ar_rev_id )
1180 - $this->mForm->prevId[$row->ar_rev_id] = $rev_id;
1181 -
1182 - $rev_id = $row->ar_rev_id;
1183 - }
1184 -
1185 - $batch->execute();
1186 - $this->mResult->seek( 0 );
1187 -
1188 - wfProfileOut( __METHOD__ );
1189 - return '';
1190 - }
1191 -
1192 - function formatRow( $row ) {
1193 - $block = new Block;
1194 - return $this->mForm->formatRevisionRow( $row );
1195 - }
1196 -
1197 - function getQueryInfo() {
1198 - $conds = $this->mConds;
1199 - $conds['ar_namespace'] = $this->title->getNamespace();
1200 - $conds['ar_title'] = $this->title->getDBkey();
1201 - return array(
1202 - 'tables' => array('archive'),
1203 - 'fields' => array( 'ar_minor_edit', 'ar_timestamp', 'ar_user', 'ar_user_text', 'ar_comment',
1204 - 'ar_rev_id', 'ar_text_id', 'ar_len', 'ar_deleted' ),
1205 - 'conds' => $conds
1206 - );
1207 - }
1208 -
1209 - function getIndexField() {
1210 - return 'ar_timestamp';
1211 - }
1212 -}
Index: trunk/phase3/includes/Linker.php
@@ -442,7 +442,6 @@
443443 * @param boolean $thumb shows image as thumbnail in a frame
444444 * @param string $manualthumb image name for the manual thumbnail
445445 * @param string $valign vertical alignment: baseline, sub, super, top, text-top, middle, bottom, text-bottom
446 - * @param string $time, timestamp (for image versioning)
447446 * @return string
448447 */
449448 function makeImageLinkObj( $title, $label, $alt, $align = '', $handlerParams = array(), $framed = false,
@@ -872,13 +871,10 @@
873872 /**
874873 * Generate a user link if the current user is allowed to view it
875874 * @param $rev Revision object.
876 - * @param $isPublic, bool, show only if all users can see it
877875 * @return string HTML
878876 */
879 - function revUserLink( $rev, $isPublic = false ) {
880 - if( $rev->isDeleted( Revision::DELETED_USER ) && $isPublic ) {
881 - $link = wfMsgHtml( 'rev-deleted-user' );
882 - } else if( $rev->userCan( Revision::DELETED_USER ) ) {
 877+ function revUserLink( $rev ) {
 878+ if( $rev->userCan( Revision::DELETED_USER ) ) {
883879 $link = $this->userLink( $rev->getRawUser(), $rev->getRawUserText() );
884880 } else {
885881 $link = wfMsgHtml( 'rev-deleted-user' );
@@ -888,74 +884,21 @@
889885 }
890886 return $link;
891887 }
892 -
893 - /**
894 - * Generate a user link if the current user is allowed to view it
895 - * @param $event, log row item.
896 - * @param $isPublic, bool, show only if all users can see it
897 - * @return string HTML
898 - */
899 - function logUserLink( $event, $isPublic = false ) {
900 - if( LogViewer::isDeleted( $event, LogViewer::DELETED_USER ) && $isPublic ) {
901 - $link = wfMsgHtml( 'rev-deleted-user' );
902 - } else if( LogViewer::userCan( $event, LogViewer::DELETED_USER ) ) {
903 - if ( isset($event->user_name) ) {
904 - $link = $this->userLink( $event->log_user, $event->user_name );
905 - } else {
906 - $user = $event->log_user;
907 - $link = $this->userLink( $event->log_user, User::whoIs( $user ) );
908 - }
909 - } else {
910 - $link = wfMsgHtml( 'rev-deleted-user' );
911 - }
912 - if( LogViewer::isDeleted( $event, LogViewer::DELETED_USER ) ) {
913 - return '<span class="history-deleted">' . $link . '</span>';
914 - }
915 - return $link;
916 - }
917888
918889 /**
919890 * Generate a user tool link cluster if the current user is allowed to view it
920891 * @param $rev Revision object.
921 - * @param $isPublic, bool, show only if all users can see it
922892 * @return string HTML
923893 */
924 - function revUserTools( $rev, $isPublic = false ) {
925 - if( $rev->isDeleted( Revision::DELETED_USER ) && $isPublic ) {
926 - $link = wfMsgHtml( 'rev-deleted-user' );
927 - } else if( $rev->userCan( Revision::DELETED_USER ) ) {
 894+ function revUserTools( $rev ) {
 895+ if( $rev->userCan( Revision::DELETED_USER ) ) {
928896 $link = $this->userLink( $rev->getRawUser(), $rev->getRawUserText() ) .
929 - ' ' . $this->userToolLinks( $rev->getRawUser(), $rev->getRawUserText() );
 897+ ' ' .
 898+ $this->userToolLinks( $rev->getRawUser(), $rev->getRawUserText() );
930899 } else {
931900 $link = wfMsgHtml( 'rev-deleted-user' );
932901 }
933902 if( $rev->isDeleted( Revision::DELETED_USER ) ) {
934 - return ' <span class="history-deleted">' . $link . '</span>';
935 - }
936 - return " $link";
937 - }
938 -
939 - /**
940 - * Generate a user tool link cluster if the current user is allowed to view it
941 - * @param $event, log item.
942 - * @param $isPublic, bool, show only if all users can see it
943 - * @return string HTML
944 - */
945 - function logUserTools( $event, $isPublic = false ) {
946 - if( LogViewer::isDeleted( $event, LogViewer::DELETED_USER ) && $isPublic ) {
947 - $link = wfMsgHtml( 'rev-deleted-user' );
948 - } else if( LogViewer::userCan( $event, LogViewer::DELETED_USER ) ) {
949 - if( isset($event->user_name) ) {
950 - $link = $this->userLink( $event->log_user, $event->user_name ) .
951 - $this->userToolLinksRedContribs( $event->log_user, $event->user_name );
952 - } else {
953 - $link = $this->userLink( $event->log_user, $event->user_name ) .
954 - $this->userToolLinksRedContribs( $event->log_user, User::whoIs($event->log_user) );
955 - }
956 - } else {
957 - $link = wfMsgHtml( 'rev-deleted-user' );
958 - }
959 - if( LogViewer::isDeleted( $event, LogViewer::DELETED_USER ) ) {
960903 return '<span class="history-deleted">' . $link . '</span>';
961904 }
962905 return $link;
@@ -1113,43 +1056,20 @@
11141057 *
11151058 * @param Revision $rev
11161059 * @param bool $local Whether section links should refer to local page
1117 - * @param $isPublic, show only if all users can see it
11181060 * @return string HTML
11191061 */
1120 - function revComment( Revision $rev, $local = false, $isPublic = false ) {
1121 - if( $rev->isDeleted( Revision::DELETED_COMMENT ) && $isPublic ) {
1122 - $block = " <span class=\"comment\">" . wfMsgHtml( 'rev-deleted-comment' ) . "</span>";
1123 - } else if( $rev->userCan( Revision::DELETED_COMMENT ) ) {
 1062+ function revComment( Revision $rev, $local = false ) {
 1063+ if( $rev->userCan( Revision::DELETED_COMMENT ) ) {
11241064 $block = $this->commentBlock( $rev->getRawComment(), $rev->getTitle(), $local );
11251065 } else {
1126 - $block = " <span class=\"comment\">" . wfMsgHtml( 'rev-deleted-comment' ) . "</span>";
 1066+ $block = " <span class=\"comment\">" .
 1067+ wfMsgHtml( 'rev-deleted-comment' ) . "</span>";
11271068 }
11281069 if( $rev->isDeleted( Revision::DELETED_COMMENT ) ) {
11291070 return " <span class=\"history-deleted\">$block</span>";
11301071 }
11311072 return $block;
11321073 }
1133 -
1134 - /**
1135 - * Wrap and format the given event's comment block, if the current
1136 - * user is allowed to view it.
1137 - *
1138 - * @param Revision $rev
1139 - * @return string HTML
1140 - */
1141 - function logComment( $event, $isPublic = false ) {
1142 - if( LogViewer::isDeleted( $event, LogViewer::DELETED_COMMENT ) && $isPublic ) {
1143 - $block = ' ' . wfMsgHtml( 'rev-deleted-comment' );
1144 - } else if( LogViewer::userCan( $event, LogViewer::DELETED_COMMENT ) ) {
1145 - $block = $this->commentBlock( LogViewer::getRawComment( $event ) );
1146 - } else {
1147 - $block = ' ' . wfMsgHtml( 'rev-deleted-comment' );
1148 - }
1149 - if( LogViewer::isDeleted( $event, LogViewer::DELETED_COMMENT ) ) {
1150 - return "<span class=\"history-deleted\">$block</span>";
1151 - }
1152 - return $block;
1153 - }
11541074
11551075 /** @todo document */
11561076 function tocIndent() {
Index: trunk/phase3/includes/DefaultSettings.php
@@ -170,16 +170,10 @@
171171 * $wgFileStore['deleted']['directory'] = '/var/wiki/private/deleted';
172172 *
173173 */
174 -// For deleted images, gererally were all versions of the image are discarded
175174 $wgFileStore = array();
176175 $wgFileStore['deleted']['directory'] = false;// Defaults to $wgUploadDirectory/deleted
177176 $wgFileStore['deleted']['url'] = null; // Private
178177 $wgFileStore['deleted']['hash'] = 3; // 3-level subdirectory split
179 -// For revisions of images marked as hidden
180 -// These are kept even if $wgSaveDeletedFiles is set to false
181 -$wgFileStore['hidden']['directory'] = false;// Defaults to $wgUploadDirectory/hidden
182 -$wgFileStore['hidden']['url'] = null; // Private
183 -$wgFileStore['hidden']['hash'] = 3; // 3-level subdirectory split
184178
185179 /**#@+
186180 * File repository structures
@@ -1066,7 +1060,6 @@
10671061 $wgGroupPermissions['sysop']['block'] = true;
10681062 $wgGroupPermissions['sysop']['createaccount'] = true;
10691063 $wgGroupPermissions['sysop']['delete'] = true;
1070 -$wgGroupPermissions['sysop']['browsearchive'] = true; // can see the deleted page list
10711064 $wgGroupPermissions['sysop']['deletedhistory'] = true; // can view deleted history entries, but not see or restore the text
10721065 $wgGroupPermissions['sysop']['editinterface'] = true;
10731066 $wgGroupPermissions['sysop']['editusercssjs'] = true;
@@ -1086,22 +1079,15 @@
10871080 $wgGroupPermissions['sysop']['autoconfirmed'] = true;
10881081 $wgGroupPermissions['sysop']['upload_by_url'] = true;
10891082 $wgGroupPermissions['sysop']['ipblock-exempt'] = true;
1090 -$wgGroupPermissions['sysop']['deleterevision'] = true;
10911083 $wgGroupPermissions['sysop']['blockemail'] = true;
1092 -$wgGroupPermissions['sysop']['mergehistory'] = true;
10931084
10941085 // Permission to change users' group assignments
10951086 $wgGroupPermissions['bureaucrat']['userrights'] = true;
10961087
1097 -// To hide usernames
1098 -$wgGroupPermissions['oversight']['hideuser'] = true;
1099 -// To see hidden revs and unhide revs hidden from Sysops
1100 -$wgGroupPermissions['oversight']['hiderevision'] = true;
1101 -// For private log access
1102 -$wgGroupPermissions['oversight']['oversight'] = true;
 1088+// Experimental permissions, not ready for production use
 1089+//$wgGroupPermissions['sysop']['deleterevision'] = true;
 1090+//$wgGroupPermissions['bureaucrat']['hiderevision'] = true;
11031091
1104 -$wgAllowLogDeletion = false;
1105 -
11061092 /**
11071093 * The developer group is deprecated, but can be activated if need be
11081094 * to use the 'lockdb' and 'unlockdb' special pages. Those require
@@ -2257,21 +2243,9 @@
22582244 'move',
22592245 'import',
22602246 'patrol',
2261 - 'merge',
2262 - 'oversight',
22632247 );
22642248
22652249 /**
2266 - * This restricts log access to those who have a certain right
2267 - * Users without this will not see it in the option menu and can not view it
2268 - * Restricted logs are not added to recent changes
2269 - * Logs should remain non-transcludable
2270 - */
2271 -$wgLogRestrictions = array(
2272 - 'oversight' => 'oversight'
2273 -);
2274 -
2275 -/**
22762250 * Lists the message key string for each log type. The localized messages
22772251 * will be listed in the user interface.
22782252 *
@@ -2287,8 +2261,6 @@
22882262 'move' => 'movelogpage',
22892263 'import' => 'importlogpage',
22902264 'patrol' => 'patrol-log-page',
2291 - 'merge' => 'mergelog',
2292 - 'oversight' => 'oversightlog',
22932265 );
22942266
22952267 /**
@@ -2307,8 +2279,6 @@
23082280 'move' => 'movelogpagetext',
23092281 'import' => 'importlogpagetext',
23102282 'patrol' => 'patrol-log-header',
2311 - 'merge' => 'mergelogpagetext',
2312 - 'oversight' => 'overlogpagetext',
23132283 );
23142284
23152285 /**
@@ -2318,29 +2288,22 @@
23192289 * Extensions with custom log types may add to this array.
23202290 */
23212291 $wgLogActions = array(
2322 - 'block/block' => 'blocklogentry',
2323 - 'block/unblock' => 'unblocklogentry',
2324 - 'protect/protect' => 'protectedarticle',
2325 - 'protect/modify' => 'modifiedarticleprotection',
2326 - 'protect/unprotect' => 'unprotectedarticle',
2327 - 'rights/rights' => 'rightslogentry',
2328 - 'delete/delete' => 'deletedarticle',
2329 - 'delete/restore' => 'undeletedarticle',
2330 - 'delete/revision' => 'revdelete-logentry',
2331 - 'delete/event' => 'logdelete-logentry',
2332 - 'upload/upload' => 'uploadedimage',
2333 - 'upload/overwrite' => 'overwroteimage',
2334 - 'upload/revert' => 'uploadedimage',
2335 - 'move/move' => '1movedto2',
2336 - 'move/move_redir' => '1movedto2_redir',
2337 - 'import/upload' => 'import-logentry-upload',
2338 - 'import/interwiki' => 'import-logentry-interwiki',
2339 - 'merge/merge' => 'pagemerge-logentry',
2340 - 'oversight/revision' => 'revdelete-logentry',
2341 - 'oversight/file' => 'revdelete-logentry',
2342 - 'oversight/event' => 'logdelete-logentry',
2343 - 'oversight/delete' => 'suppressedarticle',
2344 - 'oversight/block' => 'blocklogentry',
 2292+ 'block/block' => 'blocklogentry',
 2293+ 'block/unblock' => 'unblocklogentry',
 2294+ 'protect/protect' => 'protectedarticle',
 2295+ 'protect/modify' => 'modifiedarticleprotection',
 2296+ 'protect/unprotect' => 'unprotectedarticle',
 2297+ 'rights/rights' => 'rightslogentry',
 2298+ 'delete/delete' => 'deletedarticle',
 2299+ 'delete/restore' => 'undeletedarticle',
 2300+ 'delete/revision' => 'revdelete-logentry',
 2301+ 'upload/upload' => 'uploadedimage',
 2302+ 'upload/overwrite' => 'overwroteimage',
 2303+ 'upload/revert' => 'uploadedimage',
 2304+ 'move/move' => '1movedto2',
 2305+ 'move/move_redir' => '1movedto2_redir',
 2306+ 'import/upload' => 'import-logentry-upload',
 2307+ 'import/interwiki' => 'import-logentry-interwiki',
23452308 );
23462309
23472310 /**
Index: trunk/phase3/includes/SpecialBlockip.php
@@ -227,35 +227,34 @@
228228 </td>
229229 </tr>
230230 ");
231 -
232 - global $wgSysopEmailBans;
233 - if ( $wgSysopEmailBans && $wgUser->isAllowed( 'blockemail' ) ) {
 231+ // Allow some users to hide name from block log, blocklist and listusers
 232+ if ( $wgUser->isAllowed( 'hideuser' ) ) {
234233 $wgOut->addHTML("
235234 <tr>
236235 <td>&nbsp;</td>
237236 <td>
238 - " . wfCheckLabel( wfMsgHtml( 'ipbemailban' ),
239 - 'wpEmailBan', 'wpEmailBan', $this->BlockEmail,
240 - array( 'tabindex' => '10' )) . "
 237+ " . wfCheckLabel( wfMsgHtml( 'ipbhidename' ),
 238+ 'wpHideName', 'wpHideName', $this->BlockHideName,
 239+ array( 'tabindex' => '9' ) ) . "
241240 </td>
242241 </tr>
243242 ");
244243 }
245244
246 - // Allow some users to hide name from block log, blocklist and listusers
247 - if ( $wgUser->isAllowed( 'hideuser' ) ) {
 245+ global $wgSysopEmailBans;
 246+
 247+ if ( $wgSysopEmailBans && $wgUser->isAllowed( 'blockemail' ) ) {
248248 $wgOut->addHTML("
249249 <tr id='wpEnableEmailBan'>
250250 <td>&nbsp;</td>
251251 <td>
252 - " . wfCheckLabel( wfMsgHtml( 'ipbhidename' ),
253 - 'wpHideName', 'wpHideName', $this->BlockHideName,
254 - array( 'tabindex' => '9' ) ) . "
 252+ " . wfCheckLabel( wfMsgHtml( 'ipbemailban' ),
 253+ 'wpEmailBan', 'wpEmailBan', $this->BlockEmail,
 254+ array( 'tabindex' => '10' )) . "
255255 </td>
256256 </tr>
257257 ");
258258 }
259 -
260259 $wgOut->addHTML("
261260 <tr>
262261 <td style='padding-top: 1em'>&nbsp;</td>
Index: trunk/phase3/includes/LogPage.php
@@ -50,7 +50,7 @@
5151 function saveContent() {
5252 if( wfReadOnly() ) return false;
5353
54 - global $wgUser, $wgLogRestrictions;
 54+ global $wgUser;
5555 $fname = 'LogPage::saveContent';
5656
5757 $dbw = wfGetDB( DB_MASTER );
@@ -68,18 +68,20 @@
6969 'log_comment' => $this->comment,
7070 'log_params' => $this->params
7171 );
 72+
 73+ # log_id doesn't exist on Wikimedia servers yet, and it's a tricky
 74+ # schema update to do. Hack it for now to ignore the field on MySQL.
 75+ if ( !is_null( $log_id ) ) {
 76+ $data['log_id'] = $log_id;
 77+ }
7278 $dbw->insert( 'logging', $data, $fname );
73 - $newId = $dbw->insertId();
7479
7580 # 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 - $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, $newId );
83 - }
 81+ if ( $this->updateRecentChanges ) {
 82+ $titleObj = SpecialPage::getTitleFor( 'Log', $this->type );
 83+ $rcComment = $this->getRcComment();
 84+ RecentChange::notifyLog( $now, $titleObj, $wgUser, $rcComment, '',
 85+ $this->type, $this->action, $this->target, $this->comment, $this->params );
8486 }
8587 return true;
8688 }
@@ -131,7 +133,7 @@
132134 */
133135 static function logHeader( $type ) {
134136 global $wgLogHeaders;
135 - return wfMsgHtml( $wgLogHeaders[$type] );
 137+ return wfMsg( $wgLogHeaders[$type] );
136138 }
137139
138140 /**
@@ -171,11 +173,6 @@
172174 $text = $wgContLang->ucfirst( $title->getText() );
173175 $titleLink = $skin->makeLinkObj( Title::makeTitle( NS_USER, $text ) );
174176 break;
175 - case 'merge':
176 - $titleLink = $skin->makeLinkObj( $title, $title->getPrefixedText(), 'redirect=no' );
177 - $params[0] = $skin->makeLinkObj( Title::newFromText( $params[0] ), htmlspecialchars( $params[0] ) );
178 - $params[1] = $wgLang->timeanddate( $params[1] );
179 - break;
180177 default:
181178 $titleLink = $skin->makeLinkObj( $title );
182179 }
@@ -202,7 +199,7 @@
203200 }
204201 } else {
205202 array_unshift( $params, $titleLink );
206 - if ( $key == 'block/block' || $key == 'oversight/block' ) {
 203+ if ( $key == 'block/block' ) {
207204 if ( $skin ) {
208205 $params[1] = '<span title="' . htmlspecialchars( $params[1] ). '">' . $wgLang->translateBlockExpiry( $params[1] ) . '</span>';
209206 } else {
Index: trunk/phase3/includes/SpecialRevisiondelete.php
@@ -1,58 +1,38 @@
22 <?php
33
44 /**
5 - * Special page allowing users with the appropriate permissions to view
6 - * and hide revisions. Log items can also be hidden.
 5+ * Not quite ready for production use yet; need to fix up the restricted mode,
 6+ * and provide for preservation across delete/undelete of the page.
77 *
8 - * @addtogroup SpecialPage
 8+ * To try this out, set up extra permissions something like:
 9+ * $wgGroupPermissions['sysop']['deleterevision'] = true;
 10+ * $wgGroupPermissions['bureaucrat']['hiderevision'] = true;
911 */
1012
1113 function wfSpecialRevisiondelete( $par = null ) {
12 - global $wgOut, $wgRequest, $wgUser, $wgAllowLogDeletion;
13 - # Handle our many different possible input types
14 - $target = $wgRequest->getText( 'target' );
15 - $oldid = $wgRequest->getArray( 'oldid' );
16 - $artimestamp = $wgRequest->getArray( 'artimestamp' );
17 - $logid = $wgAllowLogDeletion ? $wgRequest->getArray( 'logid' ) : '';
18 - $image = $wgRequest->getArray( 'oldimage' );
19 - $fileid = $wgRequest->getArray( 'fileid' );
20 - # For reviewing deleted files...
21 - $file = $wgRequest->getVal( 'file' );
22 - # If this is a revision, then we need a target page
 14+ global $wgOut, $wgRequest;
 15+
 16+ $target = $wgRequest->getVal( 'target' );
 17+ $oldid = $wgRequest->getIntArray( 'oldid' );
 18+
2319 $page = Title::newFromUrl( $target );
24 - if( is_null($page) && is_null($logid) ) {
25 - $wgOut->addWikiText( wfMsgHtml( 'undelete-header' ) );
 20+
 21+ if( is_null( $page ) ) {
 22+ $wgOut->showErrorPage( 'notargettitle', 'notargettext' );
2623 return;
2724 }
28 - # Only one target set at a time please!
29 - $inputs = !empty($file) + !empty($oldid) + !empty($logid) + !empty($artimestamp) +
30 - !empty($fileid) + !empty($image);
3125
32 - if( $inputs > 1 || $inputs==0 ) {
 26+ if( is_null( $oldid ) ) {
3327 $wgOut->showErrorPage( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
3428 return;
3529 }
36 - # Either submit or create our form
37 - $form = new RevisionDeleteForm( $page, $oldid, $logid, $artimestamp, $fileid, $image, $file );
 30+
 31+ $form = new RevisionDeleteForm( $wgRequest );
3832 if( $wgRequest->wasPosted() ) {
3933 $form->submit( $wgRequest );
40 - } else if( $oldid || $artimestamp ) {
41 - $form->showRevs( $wgRequest );
42 - } else if( $fileid || $image ) {
43 - $form->showImages( $wgRequest );
44 - } else if( $logid ) {
45 - $form->showEvents( $wgRequest );
 34+ } else {
 35+ $form->show( $wgRequest );
4636 }
47 - # Show relevant lines from the deletion log
48 - # This will show even if said ID does not exist...might be helpful
49 - if( !is_null($page) ) {
50 - $wgOut->addHTML( "<h2>" . htmlspecialchars( LogPage::logName( 'delete' ) ) . "</h2>\n" );
51 - $logViewer = new LogViewer(
52 - new LogReader(
53 - new FauxRequest(
54 - array( 'page' => $page->getPrefixedText(), 'type' => 'delete' ) ) ) );
55 - $logViewer->showList( $wgOut );
56 - }
5737 }
5838
5939 /**
@@ -62,410 +42,54 @@
6343 class RevisionDeleteForm {
6444 /**
6545 * @param Title $page
66 - * @param array $oldids
67 - * @param array $logids
68 - * @param array $artimestamps
69 - * @param array $fileids
70 - * @param array $oldimages
71 - * @param string $file
 46+ * @param int $oldid
7247 */
73 - function __construct( $page, $oldids=null, $logids=null, $artimestamps=null, $fileids=null, $oldimages=null, $file=null ) {
 48+ function __construct( $request ) {
7449 global $wgUser;
75 -
76 - $this->page = $page;
77 - $this->skin = $wgUser->getSkin();
7850
79 - // For reviewing deleted files
80 - if( $file ) {
81 - $oimage = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName( $page, $file );
82 - $oimage->load();
83 - // Check if user is allowed to see this file
84 - if( !$oimage->userCan(File::DELETED_FILE) ) {
85 - $wgOut->permissionRequired( 'hiderevision' );
86 - return false;
87 - } else {
88 - return $this->showFile( $file );
89 - }
90 - }
91 - // At this point, we should only have one of these
92 - if( $oldids ) {
93 - $this->revisions = $oldids;
94 - $hide_content_name = array( 'revdelete-hide-text', 'wpHideText', Revision::DELETED_TEXT );
95 - $this->deletetype='oldid';
96 - } else if( $artimestamps ) {
97 - $this->archrevs = $artimestamps;
98 - $hide_content_name = array( 'revdelete-hide-text', 'wpHideText', Revision::DELETED_TEXT );
99 - $this->deletetype='artimestamp';
100 - } else if( $oldimages ) {
101 - $this->ofiles = $oldimages;
102 - $hide_content_name = array( 'revdelete-hide-image', 'wpHideImage', File::DELETED_FILE );
103 - $this->deletetype='oldimage';
104 - } else if( $fileids ) {
105 - $this->afiles = $fileids;
106 - $hide_content_name = array( 'revdelete-hide-image', 'wpHideImage', File::DELETED_FILE );
107 - $this->deletetype='fileid';
108 - } else if( $logids ) {
109 - $this->events = $logids;
110 - $hide_content_name = array( 'revdelete-hide-name', 'wpHideName', LogViewer::DELETED_ACTION );
111 - $this->deletetype='logid';
112 - }
113 - // Our checkbox messages depends one what we are doing,
114 - // e.g. we don't hide "text" for logs or images
 51+ $target = $request->getVal( 'target' );
 52+ $this->page = Title::newFromUrl( $target );
 53+
 54+ $this->revisions = $request->getIntArray( 'oldid', array() );
 55+
 56+ $this->skin = $wgUser->getSkin();
11557 $this->checks = array(
116 - $hide_content_name,
 58+ array( 'revdelete-hide-text', 'wpHideText', Revision::DELETED_TEXT ),
11759 array( 'revdelete-hide-comment', 'wpHideComment', Revision::DELETED_COMMENT ),
11860 array( 'revdelete-hide-user', 'wpHideUser', Revision::DELETED_USER ),
11961 array( 'revdelete-hide-restricted', 'wpHideRestricted', Revision::DELETED_RESTRICTED ) );
12062 }
12163
12264 /**
123 - * Show a deleted file version requested by the visitor.
124 - */
125 - function showFile( $key ) {
126 - global $wgOut, $wgRequest;
127 - $wgOut->disable();
128 -
129 - # We mustn't allow the output to be Squid cached, otherwise
130 - # if an admin previews a deleted image, and it's cached, then
131 - # a user without appropriate permissions can toddle off and
132 - # nab the image, and Squid will serve it
133 - $wgRequest->response()->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
134 - $wgRequest->response()->header( 'Cache-Control: no-cache, no-store, max-age=0, must-revalidate' );
135 - $wgRequest->response()->header( 'Pragma: no-cache' );
136 -
137 - $store = FileStore::get( 'hidden' );
138 - $store->stream( $key );
139 - }
140 -
141 - /**
142 - * This lets a user set restrictions for live and archived revisions
14365 * @param WebRequest $request
14466 */
145 - function showRevs( $request ) {
146 - global $wgOut, $wgUser, $action;
 67+ function show( $request ) {
 68+ global $wgOut, $wgUser;
14769
148 - $UserAllowed = true;
 70+ $wgOut->addWikiText( wfMsg( 'revdelete-selected', $this->page->getPrefixedText() ) );
14971
150 - $count = ($this->deletetype=='oldid') ?
151 - count($this->revisions) : count($this->archrevs);
152 - $wgOut->addWikiText( wfMsgExt( 'revdelete-selected', array('parsemag'),
153 - $this->page->getPrefixedText(), $count ) );
154 -
155 - $bitfields = 0;
15672 $wgOut->addHtml( "<ul>" );
157 -
158 - $where = $revObjs = array();
159 - $dbr = wfGetDB( DB_SLAVE );
160 - // Live revisions...
161 - if( $this->deletetype=='oldid' ) {
162 - // Run through and pull all our data in one query
163 - foreach( $this->revisions as $revid ) {
164 - $where[] = intval($revid);
165 - }
166 - $whereClause = 'rev_id IN(' . implode(',',$where) . ')';
167 - $result = $dbr->select( 'revision', '*',
168 - array( 'rev_page' => $this->page->getArticleID(),
169 - $whereClause ),
170 - __METHOD__ );
171 - while( $row = $dbr->fetchObject( $result ) ) {
172 - $revObjs[$row->rev_id] = new Revision( $row );
173 - }
174 - foreach( $this->revisions as $revid ) {
175 - // Hiding top revisison is bad
176 - if( !is_object($revObjs[$revid]) || $revObjs[$revid]->isCurrent() ) {
177 - $wgOut->showErrorPage( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
178 - return;
179 - } else if( !$revObjs[$revid]->userCan(Revision::DELETED_RESTRICTED) ) {
180 - // If a rev is hidden from sysops
181 - if( $action != 'submit') {
182 - $wgOut->permissionRequired( 'hiderevision' );
183 - return;
184 - }
185 - $UserAllowed = false;
186 - }
187 - $wgOut->addHtml( $this->historyLine( $revObjs[$revid] ) );
188 - $bitfields |= $revObjs[$revid]->mDeleted;
189 - }
190 - // The archives...
191 - } else {
192 - // Run through and pull all our data in one query
193 - foreach( $this->archrevs as $timestamp ) {
194 - $where[] = $dbr->addQuotes( $timestamp );
195 - }
196 - $whereClause = 'ar_timestamp IN(' . implode(',',$where) . ')';
197 - $result = $dbr->select( 'archive', '*',
198 - array( 'ar_namespace' => $this->page->getNamespace(),
199 - 'ar_title' => $this->page->getDBKey(),
200 - $whereClause ),
201 - __METHOD__ );
202 - while( $row = $dbr->fetchObject( $result ) ) {
203 - $revObjs[$row->ar_timestamp] = new Revision( array(
204 - 'page' => $this->page->getArticleId(),
205 - 'id' => $row->ar_rev_id,
206 - 'text' => $row->ar_text_id,
207 - 'comment' => $row->ar_comment,
208 - 'user' => $row->ar_user,
209 - 'user_text' => $row->ar_user_text,
210 - 'timestamp' => $row->ar_timestamp,
211 - 'minor_edit' => $row->ar_minor_edit,
212 - 'text_id' => $row->ar_text_id,
213 - 'deleted' => $row->ar_deleted,
214 - 'len' => $row->ar_len) );
215 - }
216 - foreach( $this->archrevs as $timestamp ) {
217 - if( !is_object($revObjs[$timestamp]) ) {
218 - $wgOut->showErrorPage( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
219 - return;
220 - }
221 - }
222 - foreach( $revObjs as $rev ) {
223 - if( !$rev->userCan(Revision::DELETED_RESTRICTED) ) {
224 - //if a rev is hidden from sysops
225 - if( $action != 'submit') {
226 - $wgOut->permissionRequired( 'hiderevision' );
227 - return;
228 - }
229 - $UserAllowed = false;
230 - }
231 - $wgOut->addHtml( $this->historyLine( $rev ) );
232 - $bitfields |= $rev->mDeleted;
233 - }
234 - }
235 - $wgOut->addHtml( "</ul>" );
236 -
237 - $wgOut->addWikiText( wfMsgHtml( 'revdelete-text' ) );
238 - //Normal sysops can always see what they did, but can't always change it
239 - if( !$UserAllowed ) return;
240 -
241 - $items = array(
242 - wfInputLabel( wfMsgHtml( 'revdelete-log' ), 'wpReason', 'wpReason', 60 ),
243 - wfSubmitButton( wfMsgHtml( 'revdelete-submit' ) ) );
244 - $hidden = array(
245 - wfHidden( 'wpEditToken', $wgUser->editToken() ),
246 - wfHidden( 'target', $this->page->getPrefixedText() ),
247 - wfHidden( 'type', $this->deletetype ) );
248 - if( $this->deletetype=='oldid' ) {
249 - foreach( $revObjs as $rev )
250 - $hidden[] = wfHidden( 'oldid[]', $rev->getID() );
251 - } else {
252 - foreach( $revObjs as $rev )
253 - $hidden[] = wfHidden( 'artimestamp[]', $rev->getTimestamp() );
254 - }
255 - $special = SpecialPage::getTitleFor( 'Revisiondelete' );
256 - $wgOut->addHtml( wfElement( 'form', array(
257 - 'method' => 'post',
258 - 'action' => $special->getLocalUrl( 'action=submit' ) ),
259 - null ) );
260 -
261 - $wgOut->addHtml( '<fieldset><legend>' . wfMsgHtml( 'revdelete-legend' ) . '</legend>' );
262 - // FIXME: all items checked for just one rev are checked, even if not set for the others
263 - foreach( $this->checks as $item ) {
264 - list( $message, $name, $field ) = $item;
265 - $wgOut->addHtml( "<div>" .
266 - wfCheckLabel( wfMsgHtml( $message), $name, $name, $bitfields & $field ) .
267 - "</div>\n" );
268 - }
269 - $wgOut->addHtml( '</fieldset>' );
270 - foreach( $items as $item ) {
271 - $wgOut->addHtml( '<p>' . $item . '</p>' );
272 - }
273 - foreach( $hidden as $item ) {
274 - $wgOut->addHtml( $item );
275 - }
276 -
277 - $wgOut->addHtml( '</form>' );
278 - }
279 -
280 - /**
281 - * This lets a user set restrictions for archived images
282 - * @param WebRequest $request
283 - */
284 - function showImages( $request ) {
285 - global $wgOut, $wgUser, $action;
286 -
287 - $UserAllowed = true;
288 -
289 - $count = ($this->deletetype=='oldimage') ? count($this->ofiles) : count($this->afiles);
290 - $wgOut->addWikiText( wfMsgExt( 'revdelete-selected', array('parsemag'), $this->page->getPrefixedText(), $count ) );
291 -
292 - $bitfields = 0;
293 - $wgOut->addHtml( "<ul>" );
294 -
295 - $where = $filesObjs = array();
296 - $dbr = wfGetDB( DB_SLAVE );
297 - // Live old revisions...
298 - if( $this->deletetype=='oldimage' ) {
299 - // Run through and pull all our data in one query
300 - foreach( $this->ofiles as $timestamp ) {
301 - $where[] = $dbr->addQuotes( $timestamp.'!'.$this->page->getDbKey() );
302 - }
303 - $whereClause = 'oi_archive_name IN(' . implode(',',$where) . ')';
304 - $result = $dbr->select( 'oldimage', '*',
305 - array( 'oi_name' => $this->page->getDbKey(),
306 - $whereClause ),
307 - __METHOD__ );
308 - while( $row = $dbr->fetchObject( $result ) ) {
309 - $filesObjs[$row->oi_archive_name] = RepoGroup::singleton()->getLocalRepo()->newFileFromRow( $row );
310 - $filesObjs[$row->oi_archive_name]->user = $row->oi_user;
311 - $filesObjs[$row->oi_archive_name]->userText = $row->oi_user_text;
312 - }
313 - // Check through our images
314 - foreach( $this->ofiles as $timestamp ) {
315 - $archivename = $timestamp.'!'.$this->page->getDbKey();
316 - if( !isset($filesObjs[$archivename]) ) {
317 - $wgOut->showErrorPage( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
318 - return;
319 - }
320 - }
321 - foreach( $filesObjs as $file ) {
322 - if( !isset($file) ) {
323 - $wgOut->showErrorPage( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
324 - return;
325 - } else if( !$file->userCan(File::DELETED_RESTRICTED) ) {
326 - // If a rev is hidden from sysops
327 - if( $action != 'submit' ) {
328 - $wgOut->permissionRequired( 'hiderevision' );
329 - return;
330 - }
331 - $UserAllowed = false;
332 - }
333 - // Inject history info
334 - $wgOut->addHtml( $this->uploadLine( $file ) );
335 - $bitfields |= $file->deleted;
336 - }
337 - // Archived files...
338 - } else {
339 - // Run through and pull all our data in one query
340 - foreach( $this->afiles as $id ) {
341 - $where[] = intval($id);
342 - }
343 - $whereClause = 'fa_id IN(' . implode(',',$where) . ')';
344 - $result = $dbr->select( 'filearchive', '*',
345 - array( 'fa_name' => $this->page->getDbKey(),
346 - $whereClause ),
347 - __METHOD__ );
348 - while( $row = $dbr->fetchObject( $result ) ) {
349 - $filesObjs[$row->fa_id] = ArchivedFile::newFromRow( $row );
350 - }
351 -
352 - foreach( $this->afiles as $fileid ) {
353 - if( !isset($filesObjs[$fileid]) ) {
354 - $wgOut->showErrorPage( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
355 - return;
356 - } else if( !$filesObjs[$fileid]->userCan(File::DELETED_RESTRICTED) ) {
357 - // If a rev is hidden from sysops
358 - if( $action != 'submit' ) {
359 - $wgOut->permissionRequired( 'hiderevision' );
360 - return;
361 - }
362 - $UserAllowed = false;
363 - }
364 - // Inject history info
365 - $wgOut->addHtml( $this->uploadLine( $filesObjs[$fileid] ) );
366 - $bitfields |= $filesObjs[$fileid]->deleted;
367 - }
368 - }
369 - $wgOut->addHtml( "</ul>" );
370 -
371 - $wgOut->addWikiText( wfMsgHtml( 'revdelete-text' ) );
372 - //Normal sysops can always see what they did, but can't always change it
373 - if( !$UserAllowed ) return;
374 -
375 - $items = array(
376 - wfInputLabel( wfMsgHtml( 'revdelete-log' ), 'wpReason', 'wpReason', 60 ),
377 - wfSubmitButton( wfMsgHtml( 'revdelete-submit' ) ) );
378 - $hidden = array(
379 - wfHidden( 'wpEditToken', $wgUser->editToken() ),
380 - wfHidden( 'target', $this->page->getPrefixedText() ),
381 - wfHidden( 'type', $this->deletetype ) );
382 - if( $this->deletetype=='oldimage' ) {
383 - foreach( $this->ofiles as $filename )
384 - $hidden[] = wfHidden( 'oldimage[]', $filename );
385 - } else {
386 - foreach( $this->afiles as $fileid )
387 - $hidden[] = wfHidden( 'fileid[]', $fileid );
388 - }
389 - $special = SpecialPage::getTitleFor( 'Revisiondelete' );
390 - $wgOut->addHtml( wfElement( 'form', array(
391 - 'method' => 'post',
392 - 'action' => $special->getLocalUrl( 'action=submit' ) ),
393 - null ) );
394 -
395 - $wgOut->addHtml( '<fieldset><legend>' . wfMsgHtml( 'revdelete-legend' ) . '</legend>' );
396 - // FIXME: all items checked for just one file are checked, even if not set for the others
397 - foreach( $this->checks as $item ) {
398 - list( $message, $name, $field ) = $item;
399 - $wgOut->addHtml( '<div>' .
400 - wfCheckLabel( wfMsgHtml( $message), $name, $name, $bitfields & $field ) .
401 - '</div>' );
402 - }
403 - $wgOut->addHtml( '</fieldset>' );
404 - foreach( $items as $item ) {
405 - $wgOut->addHtml( '<p>' . $item . '</p>' );
406 - }
407 - foreach( $hidden as $item ) {
408 - $wgOut->addHtml( $item );
409 - }
410 -
411 - $wgOut->addHtml( '</form>' );
412 - }
413 -
414 - /**
415 - * This lets a user set restrictions for log items
416 - * @param WebRequest $request
417 - */
418 - function showEvents( $request ) {
419 - global $wgOut, $wgUser, $action;
420 -
421 - $UserAllowed = true;
422 - $wgOut->addWikiText( wfMsgExt( 'logdelete-selected', array('parsemag'), count($this->events) ) );
423 -
424 - $bitfields = 0;
425 - $wgOut->addHtml( "<ul>" );
426 -
427 - $where = $logRows = array();
428 - $dbr = wfGetDB( DB_SLAVE );
429 - // Run through and pull all our data in one query
430 - foreach( $this->events as $logid ) {
431 - $where[] = intval($logid);
432 - }
433 - $whereClause = 'log_id IN(' . implode(',',$where) . ')';
434 - $result = $dbr->select( 'logging', '*',
435 - array( $whereClause ),
436 - __METHOD__ );
437 - while( $row = $dbr->fetchObject( $result ) ) {
438 - $logRows[$row->log_id] = $row;
439 - }
440 - foreach( $this->events as $logid ) {
441 - // Don't hide from oversight log!!!
442 - if( !isset( $logRows[$logid] ) || $logRows[$logid]->log_type=='oversight' ) {
 73+ foreach( $this->revisions as $revid ) {
 74+ $rev = Revision::newFromTitle( $this->page, $revid );
 75+ if( !isset( $rev ) ) {
44376 $wgOut->showErrorPage( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
44477 return;
445 - } else if( !LogViewer::userCan( $logRows[$logid],Revision::DELETED_RESTRICTED) ) {
446 - // If an event is hidden from sysops
447 - if( $action != 'submit') {
448 - $wgOut->permissionRequired( 'hiderevision' );
449 - return;
450 - }
451 - $UserAllowed = false;
45278 }
453 - $wgOut->addHtml( $this->logLine( $logRows[$logid] ) );
454 - $bitfields |= $logRows[$logid]->log_deleted;
 79+ $wgOut->addHtml( $this->historyLine( $rev ) );
 80+ $bitfields[] = $rev->mDeleted; // FIXME
45581 }
45682 $wgOut->addHtml( "</ul>" );
457 -
458 - $wgOut->addWikiText( wfMsgHtml( 'revdelete-text' ) );
459 - //Normal sysops can always see what they did, but can't always change it
460 - if( !$UserAllowed ) return;
 83+
 84+ $wgOut->addWikiText( wfMsg( 'revdelete-text' ) );
46185
46286 $items = array(
463 - wfInputLabel( wfMsgHtml( 'revdelete-log' ), 'wpReason', 'wpReason', 60 ),
464 - wfSubmitButton( wfMsgHtml( 'revdelete-submit' ) ) );
 87+ wfInputLabel( wfMsg( 'revdelete-log' ), 'wpReason', 'wpReason', 60 ),
 88+ wfSubmitButton( wfMsg( 'revdelete-submit' ) ) );
46589 $hidden = array(
46690 wfHidden( 'wpEditToken', $wgUser->editToken() ),
467 - wfHidden( 'type', $this->deletetype ) );
468 - foreach( $this->events as $logid ) {
469 - $hidden[] = wfHidden( 'logid[]', $logid );
 91+ wfHidden( 'target', $this->page->getPrefixedText() ) );
 92+ foreach( $this->revisions as $revid ) {
 93+ $hidden[] = wfHidden( 'oldid[]', $revid );
47094 }
47195
47296 $special = SpecialPage::getTitleFor( 'Revisiondelete' );
@@ -475,11 +99,10 @@
476100 null ) );
477101
478102 $wgOut->addHtml( '<fieldset><legend>' . wfMsgHtml( 'revdelete-legend' ) . '</legend>' );
479 - // FIXME: all items checked for just on event are checked, even if not set for the others
480103 foreach( $this->checks as $item ) {
481104 list( $message, $name, $field ) = $item;
482105 $wgOut->addHtml( '<div>' .
483 - wfCheckLabel( wfMsgHtml( $message), $name, $name, $bitfields & $field ) .
 106+ wfCheckLabel( wfMsg( $message), $name, $name, $rev->isDeleted( $field ) ) .
484107 '</div>' );
485108 }
486109 $wgOut->addHtml( '</fieldset>' );
@@ -500,211 +123,32 @@
501124 function historyLine( $rev ) {
502125 global $wgContLang;
503126 $date = $wgContLang->timeanddate( $rev->getTimestamp() );
504 -
505 - $difflink=''; $del = '';
506 - // Live revisions
507 - if( $this->deletetype=='oldid' ) {
508 - $difflink = '(' . $this->skin->makeKnownLinkObj( $this->page, wfMsgHtml('diff'),
509 - 'diff=' . $rev->getId() . '&oldid=prev' ) . ')';
510 - $revlink = $this->skin->makeLinkObj( $this->page, $date, 'oldid=' . $rev->getId() );
511 - } else {
512 - // Archived revisions
513 - $undelete = SpecialPage::getTitleFor( 'Undelete' );
514 - $target = $this->page->getPrefixedText();
515 - $revlink = $this->skin->makeLinkObj( $undelete, $date, "target=$target&timestamp=" . $rev->getTimestamp() );
516 - }
517 -
518 - if( $rev->isDeleted(Revision::DELETED_TEXT) ) {
519 - $revlink = '<span class="history-deleted">'.$revlink.'</span>';
520 - $del = ' <tt>' . wfMsgHtml( 'deletedrev' ) . '</tt>';
521 - if( !$rev->userCan(Revision::DELETED_TEXT) ) {
522 - $revlink = '<span class="history-deleted">'.$date.'</span>';
523 - }
524 - }
525 -
526127 return
527 - "<li> $difflink $revlink " . $this->skin->revUserLink( $rev ) . " " . $this->skin->revComment( $rev ) . "$del</li>";
 128+ "<li>" .
 129+ $this->skin->makeLinkObj( $this->page, $date, 'oldid=' . $rev->getId() ) .
 130+ " " .
 131+ $this->skin->revUserLink( $rev ) .
 132+ " " .
 133+ $this->skin->revComment( $rev ) .
 134+ "</li>";
528135 }
529136
530137 /**
531 - * @param File $file
532 - * This can work for old or archived revisions
533 - * @returns string
534 - */
535 - function uploadLine( $file ) {
536 - global $wgContLang, $wgTitle;
537 -
538 - $target = $this->page->getPrefixedText();
539 - $date = $wgContLang->timeanddate( $file->timestamp, true );
540 -
541 - $del = '';
542 - // Special:Undelete for viewing archived images
543 - if( $this->deletetype=='fileid' ) {
544 - $undelete = SpecialPage::getTitleFor( 'Undelete' );
545 - $pageLink = $this->skin->makeKnownLinkObj( $undelete, $date, "target=$target&file=$file->key" );
546 - // Revisiondelete for viewing images
547 - } else {
548 - # Hidden files...
549 - if( $file->isDeleted(File::DELETED_FILE) ) {
550 - $del = ' <tt>' . wfMsgHtml( 'deletedrev' ) . '</tt>';
551 - if( !$file->userCan(File::DELETED_FILE) ) {
552 - $pageLink = $date;
553 - } else {
554 - $pageLink = $this->skin->makeKnownLinkObj( $wgTitle, $date,
555 - "target=$target&file=$file->sha1.".$file->getExtension() );
556 - }
557 - $pageLink = '<span class="history-deleted">' . $pageLink . '</span>';
558 - # Regular files...
559 - } else {
560 - $url = $file->getUrlRel();
561 - $pageLink = "<a href=\"{$url}\">{$date}</a>";
562 - }
563 - }
564 -
565 - $data = wfMsgHtml( 'widthheight',
566 - $wgContLang->formatNum( $file->width ),
567 - $wgContLang->formatNum( $file->height ) ) .
568 - ' (' . wfMsgHtml( 'nbytes', $wgContLang->formatNum( $file->size ) ) . ')';
569 -
570 - return "<li> $pageLink " . $this->fileUserLink( $file ) . " $data " . $this->fileComment( $file ) . "$del</li>";
571 - }
572 -
573 - /**
574 - * @param Array $event row
575 - * @returns string
576 - */
577 - function logLine( $event ) {
578 - global $wgContLang;
579 -
580 - $date = $wgContLang->timeanddate( $event->log_timestamp );
581 - $paramArray = LogPage::extractParams( $event->log_params );
582 -
583 - if( !LogViewer::userCan($event,LogViewer::DELETED_ACTION) ) {
584 - $action = '<span class="history-deleted">' . wfMsgHtml('rev-deleted-event') . '</span>';
585 - } else {
586 - $title = Title::makeTitle( $event->log_namespace, $event->log_title );
587 - $action = LogPage::actionText( $event->log_type, $event->log_action, $title, $this->skin, $paramArray, true, true );
588 - if( $event->log_deleted & LogViewer::DELETED_ACTION )
589 - $action = '<span class="history-deleted">' . $action . '</span>';
590 - }
591 - return
592 - "<li>$date" . " " . $this->skin->logUserLink( $event ) . " $action " . $this->skin->logComment( $event ) . "</li>";
593 - }
594 -
595 - /**
596 - * Generate a user link if the current user is allowed to view it
597 - * @param ArchivedFile $file
598 - * @param $isPublic, bool, show only if all users can see it
599 - * @return string HTML
600 - */
601 - function fileUserLink( $file, $isPublic = false ) {
602 - if( $file->isDeleted( File::DELETED_USER ) && $isPublic ) {
603 - $link = wfMsgHtml( 'rev-deleted-user' );
604 - } else if( $file->userCan( File::DELETED_USER ) ) {
605 - $link = $this->skin->userLink( $file->user, $file->userText );
606 - } else {
607 - $link = wfMsgHtml( 'rev-deleted-user' );
608 - }
609 - if( $file->isDeleted( File::DELETED_USER ) ) {
610 - return '<span class="history-deleted">' . $link . '</span>';
611 - }
612 - return $link;
613 - }
614 -
615 - /**
616 - * Generate a user tool link cluster if the current user is allowed to view it
617 - * @param ArchivedFile $file
618 - * @param $isPublic, bool, show only if all users can see it
619 - * @return string HTML
620 - */
621 - function fileUserTools( $file, $isPublic = false ) {
622 - if( $file->isDeleted( Revision::DELETED_USER ) && $isPublic ) {
623 - $link = wfMsgHtml( 'rev-deleted-user' );
624 - } else if( $file->userCan( Revision::DELETED_USER ) ) {
625 - $link = $this->skin->userLink( $file->user, $file->userText ) .
626 - $this->userToolLinks( $file->user, $file->userText );
627 - } else {
628 - $link = wfMsgHtml( 'rev-deleted-user' );
629 - }
630 - if( $file->isDeleted( Revision::DELETED_USER ) ) {
631 - return '<span class="history-deleted">' . $link . '</span>';
632 - }
633 - return $link;
634 - }
635 -
636 - /**
637 - * Wrap and format the given file's comment block, if the current
638 - * user is allowed to view it.
639 - *
640 - * @param ArchivedFile $file
641 - * @return string HTML
642 - */
643 - function fileComment( $file, $isPublic = false ) {
644 - if( $file->isDeleted( File::DELETED_COMMENT ) && $isPublic ) {
645 - $block = ' ' . wfMsgHtml( 'rev-deleted-comment' );
646 - } else if( $file->userCan( File::DELETED_COMMENT ) ) {
647 - $block = $this->skin->commentBlock( $file->description );
648 - } else {
649 - $block = ' ' . wfMsgHtml( 'rev-deleted-comment' );
650 - }
651 - if( $file->isDeleted( File::DELETED_COMMENT ) ) {
652 - return "<span class=\"history-deleted\">$block</span>";
653 - }
654 - return $block;
655 - }
656 -
657 - /**
658138 * @param WebRequest $request
659139 */
660140 function submit( $request ) {
661141 $bitfield = $this->extractBitfield( $request );
662142 $comment = $request->getText( 'wpReason' );
663 -
664 - $this->target = $request->getText( 'target' );
665 - $this->title = Title::newFromURL( $this->target );
666 -
667 - if( $this->save( $bitfield, $comment, $this->title ) ) {
668 - $this->success( $request );
669 - } else if( $request->getCheck( 'oldid' ) || $request->getCheck( 'artimestamp' ) ) {
670 - return $this->showRevs( $request );
671 - } else if( $request->getCheck( 'logid' ) ) {
672 - return $this->showLogs( $request );
673 - } else if( $request->getCheck( 'oldimage' ) || $request->getCheck( 'fileid' ) ) {
674 - return $this->showImages( $request );
 143+ if( $this->save( $bitfield, $comment ) ) {
 144+ return $this->success( $request );
 145+ } else {
 146+ return $this->show( $request );
675147 }
676148 }
677149
678150 function success( $request ) {
679151 global $wgOut;
680 -
681 - $wgOut->setPagetitle( wfMsgHtml( 'actioncomplete' ) );
682 - # Give a link to the log for this page
683 - $logtitle = SpecialPage::getTitleFor( 'Log' );
684 - $loglink = $this->skin->makeKnownLinkObj( $logtitle, wfMsgHtml( 'viewpagelogs' ),
685 - wfArrayToCGI( array('page' => $this->target ) ) );
686 - # Give a link to the page history
687 - $histlink = $this->skin->makeKnownLinkObj( $this->title, wfMsgHtml( 'revhistory' ),
688 - wfArrayToCGI( array('action' => 'history' ) ) );
689 - # Link to deleted edits
690 - $undelete = SpecialPage::getTitleFor( 'Undelete' );
691 - $dellink = $this->skin->makeKnownLinkObj( $undelete, wfMsgHtml( 'undeleterevs' ),
692 - wfArrayToCGI( array('target' => $this->target) ) );
693 - # Logs themselves don't have histories or archived revisions
694 - if( !is_null($this->title) && $this->title->getNamespace() > -1)
695 - $wgOut->setSubtitle( '<p>'.$histlink.' / '.$loglink.' / '.$dellink.'</p>' );
696 -
697 - if( $this->deletetype=='logid' ) {
698 - $wgOut->addWikiText( wfMsgHtml('logdelete-success'), false );
699 - $this->showEvents( $request );
700 - } else if( $this->deletetype=='oldid' || $this->deletetype=='artimestamp' ) {
701 - $wgOut->addWikiText( wfMsgHtml('revdelete-success'), false );
702 - $this->showRevs( $request );
703 - } else if( $this->deletetype=='fileid' ) {
704 - $wgOut->addWikiText( wfMsgHtml('revdelete-success'), false );
705 - $this->showImages( $request );
706 - } else if( $this->deletetype=='oldimage' ) {
707 - $this->showImages( $request );
708 - }
 152+ $wgOut->addWikiText( 'woo' );
709153 }
710154
711155 /**
@@ -723,26 +167,10 @@
724168 return $bitfield;
725169 }
726170
727 - function save( $bitfield, $reason, $title ) {
 171+ function save( $bitfield, $reason ) {
728172 $dbw = wfGetDB( DB_MASTER );
729 -
730 - // Don't allow simply locking the interface for no reason
731 - if( $bitfield == Revision::DELETED_RESTRICTED )
732 - $bitfield = 0;
733 -
734173 $deleter = new RevisionDeleter( $dbw );
735 - // By this point, only one of the below should be set
736 - if( isset($this->revisions) ) {
737 - return $deleter->setRevVisibility( $title, $this->revisions, $bitfield, $reason );
738 - } else if( isset($this->archrevs) ) {
739 - return $deleter->setArchiveVisibility( $title, $this->archrevs, $bitfield, $reason );
740 - } else if( isset($this->ofiles) ) {
741 - return $deleter->setOldImgVisibility( $title, $this->ofiles, $bitfield, $reason );
742 - } else if( isset($this->afiles) ) {
743 - return $deleter->setArchFileVisibility( $title, $this->afiles, $bitfield, $reason );
744 - } else if( isset($this->events) ) {
745 - return $deleter->setEventVisibility( $this->events, $bitfield, $reason );
746 - }
 174+ $deleter->setVisibility( $this->revisions, $bitfield, $reason );
747175 }
748176 }
749177
@@ -752,510 +180,42 @@
753181 */
754182 class RevisionDeleter {
755183 function __construct( $db ) {
756 - $this->dbw = $db;
 184+ $this->db = $db;
757185 }
758186
759187 /**
760 - * @param $title, the page these events apply to
761188 * @param array $items list of revision ID numbers
762189 * @param int $bitfield new rev_deleted value
763190 * @param string $comment Comment for log records
764191 */
765 - function setRevVisibility( $title, $items, $bitfield, $comment ) {
766 - global $wgOut;
 192+ function setVisibility( $items, $bitfield, $comment ) {
 193+ $pages = array();
767194
768 - $userAllowedAll = $success = true;
769 - $revIDs = array();
770 - $revCount = 0;
771 - // Run through and pull all our data in one query
772 - foreach( $items as $revid ) {
773 - $where[] = intval($revid);
774 - }
775 - $whereClause = 'rev_id IN(' . implode(',',$where) . ')';
776 - $result = $this->dbw->select( 'revision', '*',
777 - array( 'rev_page' => $title->getArticleID(),
778 - $whereClause ),
779 - __METHOD__ );
780 - while( $row = $this->dbw->fetchObject( $result ) ) {
781 - $revObjs[$row->rev_id] = new Revision( $row );
782 - }
783195 // To work!
784196 foreach( $items as $revid ) {
785 - if( !isset($revObjs[$revid]) || $revObjs[$revid]->isCurrent() ) {
786 - $success = false;
787 - continue; // Must exist
788 - } else if( !$revObjs[$revid]->userCan(Revision::DELETED_RESTRICTED) ) {
789 - $userAllowedAll=false;
790 - continue;
 197+ $rev = Revision::newFromId( $revid );
 198+ if( !isset( $rev ) ) {
 199+ return false;
791200 }
792 - // For logging, maintain a count of revisions
793 - if( $revObjs[$revid]->mDeleted != $bitfield ) {
794 - $revCount++;
795 - $revIDs[]=$revid;
796 -
797 - $this->updateRevision( $revObjs[$revid], $bitfield );
798 - $this->updateRecentChangesEdits( $revObjs[$revid], $bitfield, false );
799 - }
800 - }
801 - // Clear caches...
802 - // Don't log or touch if nothing changed
803 - if( $revCount > 0 ) {
804 - $this->updatePage( $title );
805 - $this->updateLog( $title, $revCount, $bitfield, $revObjs[$revid]->mDeleted,
806 - $comment, $title, 'oldid', $revIDs );
807 - }
808 - // Where all revs allowed to be set?
809 - if( !$userAllowedAll ) {
810 - //FIXME: still might be confusing???
811 - $wgOut->permissionRequired( 'hiderevision' );
812 - return false;
813 - }
814 -
815 - return $success;
816 - }
817 -
818 - /**
819 - * @param $title, the page these events apply to
820 - * @param array $items list of revision ID numbers
821 - * @param int $bitfield new rev_deleted value
822 - * @param string $comment Comment for log records
823 - */
824 - function setArchiveVisibility( $title, $items, $bitfield, $comment ) {
825 - global $wgOut;
826 -
827 - $userAllowedAll = $success = true;
828 - $count = 0;
829 - $Id_set = array();
830 - // Run through and pull all our data in one query
831 - foreach( $items as $timestamp ) {
832 - $where[] = $this->dbw->addQuotes( $timestamp );
833 - }
834 - $whereClause = 'ar_timestamp IN(' . implode(',',$where) . ')';
835 - $result = $this->dbw->select( 'archive', '*',
836 - array( 'ar_namespace' => $title->getNamespace(),
837 - 'ar_title' => $title->getDBKey(),
838 - $whereClause ),
839 - __METHOD__ );
840 - while( $row = $this->dbw->fetchObject( $result ) ) {
841 - $revObjs[$row->ar_timestamp] = new Revision( array(
842 - 'page' => $title->getArticleId(),
843 - 'id' => $row->ar_rev_id,
844 - 'text' => $row->ar_text_id,
845 - 'comment' => $row->ar_comment,
846 - 'user' => $row->ar_user,
847 - 'user_text' => $row->ar_user_text,
848 - 'timestamp' => $row->ar_timestamp,
849 - 'minor_edit' => $row->ar_minor_edit,
850 - 'text_id' => $row->ar_text_id,
851 - 'deleted' => $row->ar_deleted,
852 - 'len' => $row->ar_len) );
853 - }
854 - // To work!
855 - foreach( $items as $timestamp ) {
856 - // This will only select the first revision with this timestamp.
857 - // Since they are all selected/deleted at once, we can just check the
858 - // permissions of one. UPDATE is done via timestamp, so all revs are set.
859 - if( !is_object($revObjs[$timestamp]) ) {
860 - $success = false;
861 - continue; // Must exist
862 - } else if( !$revObjs[$timestamp]->userCan(Revision::DELETED_RESTRICTED) ) {
863 - $userAllowedAll=false;
864 - continue;
865 - }
866 - // Which revisions did we change anything about?
867 - if( $revObjs[$timestamp]->mDeleted != $bitfield ) {
868 - $Id_set[]=$timestamp;
869 - $count++;
870 -
871 - $this->updateArchive( $revObjs[$timestamp], $bitfield );
872 - }
873 - }
874 - // For logging, maintain a count of revisions
875 - if( $count > 0 ) {
876 - $this->updateLog( $title, $count, $bitfield, $revObjs[$timestamp]->mDeleted,
877 - $comment, $title, 'artimestamp', $Id_set );
878 - }
879 - // Where all revs allowed to be set?
880 - if( !$userAllowedAll ) {
881 - $wgOut->permissionRequired( 'hiderevision' );
882 - return false;
883 - }
884 -
885 - return $success;
886 - }
887 -
888 - /**
889 - * @param $title, the page these events apply to
890 - * @param array $items list of revision ID numbers
891 - * @param int $bitfield new rev_deleted value
892 - * @param string $comment Comment for log records
893 - */
894 - function setOldImgVisibility( $title, $items, $bitfield, $comment ) {
895 - global $wgOut;
896 -
897 - $userAllowedAll = $success = true;
898 - $count = 0;
899 - $set = array();
900 - // Run through and pull all our data in one query
901 - foreach( $items as $timestamp ) {
902 - $where[] = $this->dbw->addQuotes( $timestamp.'!'.$title->getDbKey() );
903 - }
904 - $whereClause = 'oi_archive_name IN(' . implode(',',$where) . ')';
905 - $result = $this->dbw->select( 'oldimage', '*',
906 - array( 'oi_name' => $title->getDbKey(),
907 - $whereClause ),
908 - __METHOD__ );
909 - while( $row = $this->dbw->fetchObject( $result ) ) {
910 - $filesObjs[$row->oi_archive_name] = RepoGroup::singleton()->getLocalRepo()->newFileFromRow( $row );
911 - $filesObjs[$row->oi_archive_name]->user = $row->oi_user;
912 - $filesObjs[$row->oi_archive_name]->userText = $row->oi_user_text;
913 - }
914 - // To work!
915 - foreach( $items as $timestamp ) {
916 - $archivename = $timestamp.'!'.$title->getDbKey();
917 - if( !isset($filesObjs[$archivename]) ) {
918 - $success = false;
919 - continue; // Must exist
920 - } else if( !$filesObjs[$archivename]->userCan(File::DELETED_RESTRICTED) ) {
921 - $userAllowedAll=false;
922 - continue;
923 - }
 201+ $this->updateRevision( $rev, $bitfield );
 202+ $this->updateRecentChanges( $rev, $bitfield );
924203
925 - $transaction = true;
926 - // Which revisions did we change anything about?
927 - if( $filesObjs[$archivename]->deleted != $bitfield ) {
928 - $count++;
929 -
930 - $this->dbw->begin();
931 - $this->updateOldFiles( $filesObjs[$archivename], $bitfield );
932 - // If this image is currently hidden...
933 - if( $filesObjs[$archivename]->deleted & File::DELETED_FILE ) {
934 - if( $bitfield & File::DELETED_FILE ) {
935 - # Leave it alone if we are not changing this...
936 - $set[]=$name;
937 - $transaction = true;
938 - } else {
939 - # We are moving this out
940 - $transaction = $this->makeOldImagePublic( $filesObjs[$archivename] );
941 - $set[]=$transaction;
942 - }
943 - // Is it just now becoming hidden?
944 - } else if( $bitfield & File::DELETED_FILE ) {
945 - $transaction = $this->makeOldImagePrivate( $filesObjs[$archivename] );
946 - $set[]=$transaction;
947 - } else {
948 - $set[]=$name;
949 - }
950 - // If our file operations fail, then revert back the db
951 - if( $transaction==false ) {
952 - $this->dbw->rollback();
953 - return false;
954 - }
955 - $this->dbw->commit();
956 - // Purge page/history
957 - $filesObjs[$archivename]->purgeCache();
958 - $filesObjs[$archivename]->purgeHistory();
959 - // Invalidate cache for all pages using this file
960 - $update = new HTMLCacheUpdate( $oimage->getTitle(), 'imagelinks' );
961 - $update->doUpdate();
962 - }
963 - }
964 -
965 - // Log if something was changed
966 - if( $count > 0 ) {
967 - $this->updateLog( $title, $count, $bitfield, $filesObjs[$archivename]->deleted,
968 - $comment, $title, 'oldimage', $set );
969 - }
970 - // Where all revs allowed to be set?
971 - if( !$userAllowedAll ) {
972 - $wgOut->permissionRequired( 'hiderevision' );
973 - return false;
974 - }
975 -
976 - return $success;
977 - }
978 -
979 - /**
980 - * @param $title, the page these events apply to
981 - * @param array $items list of revision ID numbers
982 - * @param int $bitfield new rev_deleted value
983 - * @param string $comment Comment for log records
984 - */
985 - function setArchFileVisibility( $title, $items, $bitfield, $comment ) {
986 - global $wgOut;
987 -
988 - $userAllowedAll = $success = true;
989 - $count = 0;
990 - $Id_set = array();
991 -
992 - // Run through and pull all our data in one query
993 - foreach( $items as $id ) {
994 - $where[] = intval($id);
995 - }
996 - $whereClause = 'fa_id IN(' . implode(',',$where) . ')';
997 - $result = $this->dbw->select( 'filearchive', '*',
998 - array( 'fa_name' => $title->getDbKey(),
999 - $whereClause ),
1000 - __METHOD__ );
1001 - while( $row = $this->dbw->fetchObject( $result ) ) {
1002 - $filesObjs[$row->fa_id] = ArchivedFile::newFromRow( $row );
1003 - }
1004 - // To work!
1005 - foreach( $items as $fileid ) {
1006 - if( !isset($filesObjs[$fileid]) ) {
1007 - $success = false;
1008 - continue; // Must exist
1009 - } else if( !$filesObjs[$fileid]->userCan(File::DELETED_RESTRICTED) ) {
1010 - $userAllowedAll=false;
1011 - continue;
1012 - }
1013 - // Which revisions did we change anything about?
1014 - if( $filesObjs[$fileid]->deleted != $bitfield ) {
1015 - $Id_set[]=$fileid;
1016 - $count++;
1017 -
1018 - $this->updateArchFiles( $filesObjs[$fileid], $bitfield );
1019 - }
1020 - }
1021 - // Log if something was changed
1022 - if( $count > 0 ) {
1023 - $this->updateLog( $title, $count, $bitfield, $comment,
1024 - $filesObjs[$fileid]->deleted, $title, 'fileid', $Id_set );
1025 - }
1026 - // Where all revs allowed to be set?
1027 - if( !$userAllowedAll ) {
1028 - $wgOut->permissionRequired( 'hiderevision' );
1029 - return false;
1030 - }
1031 -
1032 - return $success;
1033 - }
1034 -
1035 - /**
1036 - * @param $title, the page these events apply to
1037 - * @param array $items list of log ID numbers
1038 - * @param int $bitfield new log_deleted value
1039 - * @param string $comment Comment for log records
1040 - */
1041 - function setEventVisibility( $items, $bitfield, $comment ) {
1042 - global $wgOut;
1043 -
1044 - $userAllowedAll = $success = true;
1045 - $logs_count = array();
1046 - $logs_Ids = array();
1047 -
1048 - // Run through and pull all our data in one query
1049 - foreach( $items as $logid ) {
1050 - $where[] = intval($logid);
1051 - }
1052 - $whereClause = 'log_id IN(' . implode(',',$where) . ')';
1053 - $result = $this->dbw->select( 'logging', '*',
1054 - array( $whereClause ),
1055 - __METHOD__ );
1056 - while( $row = $this->dbw->fetchObject( $result ) ) {
1057 - $logRows[$row->log_id] = $row;
1058 - }
1059 - // To work!
1060 - foreach( $items as $logid ) {
1061 - if( !isset($logRows[$logid]) ) {
1062 - $success = false;
1063 - continue; // Must exist
1064 - } else if( !LogViewer::userCan($logRows[$logid], Revision::DELETED_RESTRICTED)
1065 - || $logRows[$logid]->log_type=='oversight' ) {
1066 - // Don't hide from oversight log!!!
1067 - $userAllowedAll=false;
1068 - continue;
1069 - }
1070 - $logtype = $logRows[$logid]->log_type;
1071 - // For logging, maintain a count of events per log type
1072 - if( !isset( $logs_count[$logtype] ) ) {
1073 - $logs_count[$logtype]=0;
1074 - $logs_Ids[$logtype]=array();
1075 - }
1076 - // Which logs did we change anything about?
1077 - if( $logRows[$logid]->log_deleted != $bitfield ) {
1078 - $logs_Ids[$logtype][]=$logid;
1079 - $logs_count[$logtype]++;
1080 -
1081 - $this->updateLogs( $logRows[$logid], $bitfield );
1082 - $this->updateRecentChangesLog( $logRows[$logid], $bitfield, true );
1083 - }
1084 - }
1085 - foreach( $logs_count as $logtype => $count ) {
1086 - //Don't log or touch if nothing changed
1087 - if( $count > 0 ) {
1088 - $target = SpecialPage::getTitleFor( 'Log', $logtype );
1089 - $this->updateLog( $target, $count, $bitfield, $logRows[$logid]->log_deleted,
1090 - $comment, $target, 'logid', $logs_Ids[$logtype] );
1091 - }
1092 - }
1093 - // Where all revs allowed to be set?
1094 - if( !$userAllowedAll ) {
1095 - $wgOut->permissionRequired( 'hiderevision' );
1096 - return false;
1097 - }
1098 -
1099 - return $success;
1100 - }
1101 -
1102 - /**
1103 - * Moves an image to a safe private location
1104 - * Caller is responsible for clearing caches
1105 - * @param File $oimage
1106 - * @returns string, timestamp on success, false on failure
1107 - */
1108 - function makeOldImagePrivate( $oimage ) {
1109 - global $wgFileStore, $wgUseSquid;
1110 -
1111 - $transaction = new FSTransaction();
1112 - if( !FileStore::lock() ) {
1113 - wfDebug( __METHOD__.": failed to acquire file store lock, aborting\n" );
1114 - return false;
1115 - }
1116 - $oldpath = $oimage->getArchivePath() . DIRECTORY_SEPARATOR . $oimage->archive_name;
1117 - // Dupe the file into the file store
1118 - if( file_exists( $oldpath ) ) {
1119 - // Is our directory configured?
1120 - if( $store = FileStore::get( 'hidden' ) ) {
1121 - if( !$oimage->sha1 )
1122 - $oimage->upgradeRow();
1123 -
1124 - $key = $oimage->sha1.'.'.$oimage->getExtension();
1125 - $transaction->add( $store->insert( $key, $oldpath, FileStore::DELETE_ORIGINAL ) );
 204+ // For logging, maintain a count of revisions per page
 205+ $pageid = $rev->getPage();
 206+ if( isset( $pages[$pageid] ) ) {
 207+ $pages[$pageid]++;
1126208 } else {
1127 - $group = null;
1128 - $key = null;
1129 - $transaction = false; // Return an error and do nothing
 209+ $pages[$pageid] = 1;
1130210 }
1131 - } else {
1132 - wfDebug( __METHOD__." deleting already-missing '$oldpath'; moving on to database\n" );
1133 - $group = null;
1134 - $key = '';
1135 - $transaction = new FSTransaction(); // empty
1136211 }
1137 -
1138 - if( $transaction === false ) {
1139 - // Fail to restore?
1140 - wfDebug( __METHOD__.": import to file store failed, aborting\n" );
1141 - throw new MWException( "Could not archive and delete file $oldpath" );
1142 - return false;
1143 - }
1144212
1145 - wfDebug( __METHOD__.": set db items, applying file transactions\n" );
1146 - $transaction->commit();
1147 - FileStore::unlock();
1148 -
1149 - $m = explode('!',$oimage->archive_name,2);
1150 - $timestamp = $m[0];
1151 -
1152 - return $timestamp;
1153 - }
1154 -
1155 - /**
1156 - * Moves an image from a safe private location
1157 - * Caller is responsible for clearing caches
1158 - * @param File $oimage
1159 - * @returns string, timestamp on success, false on failure
1160 - */
1161 - function makeOldImagePublic( $oimage ) {
1162 - global $wgFileStore;
1163 -
1164 - $transaction = new FSTransaction();
1165 - if( !FileStore::lock() ) {
1166 - wfDebug( __METHOD__." could not acquire filestore lock\n" );
1167 - return false;
 213+ // Clear caches...
 214+ foreach( $pages as $pageid => $count ) {
 215+ $title = Title::newFromId( $pageid );
 216+ $this->updatePage( $title );
 217+ $this->updateLog( $title, $count, $bitfield, $comment );
1168218 }
1169219
1170 - $store = FileStore::get( 'hidden' );
1171 - if( !$store ) {
1172 - wfDebug( __METHOD__.": skipping row with no file.\n" );
1173 - return false;
1174 - }
1175 -
1176 - $key = $oimage->sha1.'.'.$oimage->getExtension();
1177 - $destDir = $oimage->getArchivePath();
1178 - if( !is_dir( $destDir ) ) {
1179 - wfMkdirParents( $destDir );
1180 - }
1181 - $destPath = $destDir . DIRECTORY_SEPARATOR . $oimage->archive_name;
1182 - // Check if any other stored revisions use this file;
1183 - // if so, we shouldn't remove the file from the hidden
1184 - // archives so they will still work.
1185 - $useCount = $this->dbw->selectField( 'oldimage','COUNT(*)',
1186 - array( 'oi_sha1' => $oimage->sha1,
1187 - 'oi_deleted & '.File::DELETED_FILE => File::DELETED_FILE ),
1188 - __METHOD__ );
1189 -
1190 - if( $useCount == 0 ) {
1191 - wfDebug( __METHOD__.": nothing else using {$oimage->sha1}, will deleting after\n" );
1192 - $flags = FileStore::DELETE_ORIGINAL;
1193 - } else {
1194 - $flags = 0;
1195 - }
1196 - $transaction->add( $store->export( $key, $destPath, $flags ) );
1197 -
1198 - wfDebug( __METHOD__.": set db items, applying file transactions\n" );
1199 - $transaction->commit();
1200 - FileStore::unlock();
1201 -
1202 - $m = explode('!',$oimage->archive_name,2);
1203 - $timestamp = $m[0];
1204 -
1205 - return $timestamp;
1206 - }
1207 -
1208 - /**
1209 - * Moves an image from a safe private location to deleted archives
1210 - * Groups should be 'deleted' and 'hidden'
1211 - * @param File $oimage
1212 - * @param string $group1, old group
1213 - * @param string $group2, new group
1214 - * @returns bool, success
1215 - */
1216 - function moveImageFromFileRepos( $oimage, $group1, $group2 ) {
1217 - global $wgFileStore;
1218 -
1219 - $transaction = new FSTransaction();
1220 - if( !FileStore::lock() ) {
1221 - wfDebug( __METHOD__." could not acquire filestore lock\n" );
1222 - return false;
1223 - }
1224 -
1225 - $storeOld = FileStore::get( $group1 );
1226 - if( !$storeOld ) {
1227 - wfDebug( __METHOD__.": skipping row with no file.\n" );
1228 - return false;
1229 - }
1230 - $key = $oimage->sha1.'.'.$oimage->getExtension();
1231 -
1232 - $oldPath = $storeOld->filePath( $key );
1233 - // Check if any other stored revisions use this file;
1234 - // if so, we shouldn't remove the file from the hidden
1235 - // archives so they will still work.
1236 - if( $group1=='hidden' ) {
1237 - $useCount = $this->dbw->selectField( 'oldimage','COUNT(*)',
1238 - array( 'oi_sha1' => $oimage->sha1 ),
1239 - __METHOD__ );
1240 - } else if( $group1=='deleted' ) {
1241 - $useCount = $this->dbw->selectField( 'filearchive','COUNT(*)',
1242 - array( 'fa_storage_key' => $key, 'fa_storage_group' => 'deleted' ),
1243 - __METHOD__ );
1244 - }
1245 -
1246 - if( $useCount == 0 ) {
1247 - wfDebug( __METHOD__.": nothing else using $key, will deleting after\n" );
1248 - $flags = FileStore::DELETE_ORIGINAL;
1249 - } else {
1250 - $flags = 0;
1251 - }
1252 -
1253 - $storeNew = FileStore::get( $group2 );
1254 - $transaction->add( $storeNew->insert( $key, $oldPath, $flags ) );
1255 -
1256 - wfDebug( __METHOD__.": set db items, applying file transactions\n" );
1257 - $transaction->commit();
1258 - FileStore::unlock();
1259 -
1260220 return true;
1261221 }
1262222
@@ -1265,87 +225,29 @@
1266226 * @param int $bitfield new rev_deleted bitfield value
1267227 */
1268228 function updateRevision( $rev, $bitfield ) {
1269 - $this->dbw->update( 'revision',
 229+ $this->db->update( 'revision',
1270230 array( 'rev_deleted' => $bitfield ),
1271231 array( 'rev_id' => $rev->getId() ),
1272232 'RevisionDeleter::updateRevision' );
1273233 }
1274234
1275235 /**
1276 - * Update the revision's rev_deleted field
1277 - * @param Revision $rev
1278 - * @param int $bitfield new rev_deleted bitfield value
1279 - */
1280 - function updateArchive( $rev, $bitfield ) {
1281 - $this->dbw->update( 'archive',
1282 - array( 'ar_deleted' => $bitfield ),
1283 - array( 'ar_rev_id' => $rev->getId() ),
1284 - 'RevisionDeleter::updateArchive' );
1285 - }
1286 -
1287 - /**
1288 - * Update the images's oi_deleted field
1289 - * @param File $oimage
1290 - * @param int $bitfield new rev_deleted bitfield value
1291 - */
1292 - function updateOldFiles( $oimage, $bitfield ) {
1293 - $this->dbw->update( 'oldimage',
1294 - array( 'oi_deleted' => $bitfield ),
1295 - array( 'oi_archive_name' => $oimage->archive_name ),
1296 - 'RevisionDeleter::updateOldFiles' );
1297 - }
1298 -
1299 - /**
1300 - * Update the images's fa_deleted field
1301 - * @param ArchivedFile $file
1302 - * @param int $bitfield new rev_deleted bitfield value
1303 - */
1304 - function updateArchFiles( $file, $bitfield ) {
1305 - $this->dbw->update( 'filearchive',
1306 - array( 'fa_deleted' => $bitfield ),
1307 - array( 'fa_id' => $file->id ),
1308 - 'RevisionDeleter::updateArchFiles' );
1309 - }
1310 -
1311 - /**
1312 - * Update the logging log_deleted field
1313 - * @param Row $event
1314 - * @param int $bitfield new rev_deleted bitfield value
1315 - */
1316 - function updateLogs( $event, $bitfield ) {
1317 - $this->dbw->update( 'logging',
1318 - array( 'log_deleted' => $bitfield ),
1319 - array( 'log_id' => $event->log_id ),
1320 - 'RevisionDeleter::updateLogs' );
1321 - }
1322 -
1323 - /**
1324236 * Update the revision's recentchanges record if fields have been hidden
1325237 * @param Revision $rev
1326238 * @param int $bitfield new rev_deleted bitfield value
1327239 */
1328 - function updateRecentChangesEdits( $rev, $bitfield ) {
1329 - $this->dbw->update( 'recentchanges',
1330 - array( 'rc_deleted' => $bitfield,
1331 - 'rc_patrolled' => 1 ),
1332 - array( 'rc_this_oldid' => $rev->getId() ),
1333 - 'RevisionDeleter::updateRecentChangesEdits' );
 240+ function updateRecentChanges( $rev, $bitfield ) {
 241+ $this->db->update( 'recentchanges',
 242+ array(
 243+ 'rc_user' => ($bitfield & Revision::DELETED_USER) ? 0 : $rev->getUser(),
 244+ 'rc_user_text' => ($bitfield & Revision::DELETED_USER) ? wfMsg( 'rev-deleted-user' ) : $rev->getUserText(),
 245+ 'rc_comment' => ($bitfield & Revision::DELETED_COMMENT) ? wfMsg( 'rev-deleted-comment' ) : $rev->getComment() ),
 246+ array(
 247+ 'rc_this_oldid' => $rev->getId() ),
 248+ 'RevisionDeleter::updateRecentChanges' );
1334249 }
1335250
1336251 /**
1337 - * Update the revision's recentchanges record if fields have been hidden
1338 - * @param Row $event
1339 - * @param int $bitfield new rev_deleted bitfield value
1340 - */
1341 - function updateRecentChangesLog( $event, $bitfield ) {
1342 - $this->dbw->update( 'recentchanges',
1343 - array( 'rc_deleted' => $bitfield,
1344 - 'rc_patrolled' => 1 ),
1345 - array( 'rc_logid' => $event->log_id ),
1346 - 'RevisionDeleter::updateRecentChangesLog' );
1347 - }
1348 -
1349 - /**
1350252 * Touch the page's cache invalidation timestamp; this forces cached
1351253 * history views to refresh, so any newly hidden or shown fields will
1352254 * update properly.
@@ -1353,39 +255,21 @@
1354256 */
1355257 function updatePage( $title ) {
1356258 $title->invalidateCache();
1357 - $title->purgeSquid();
1358 -
1359 - // Extensions that require referencing previous revisions may need this
1360 - wfRunHooks( 'ArticleRevisionVisiblitySet', array( &$title ) );
1361259 }
1362260
1363261 /**
1364262 * Record a log entry on the action
1365 - * @param Title $title, page where item was removed from
 263+ * @param Title $title
1366264 * @param int $count the number of revisions altered for this page
1367 - * @param int $nbitfield the new _deleted value
1368 - * @param int $obitfield the old _deleted value
 265+ * @param int $bitfield the new rev_deleted value
1369266 * @param string $comment
1370 - * @param Title $target, the relevant page
1371 - * @param string $param, URL param
1372 - * @param Array $items
1373267 */
1374 - function updateLog( $title, $count, $nbitfield, $obitfield, $comment, $target, $param, $items = array() ) {
1375 - // Put things hidden from sysops in the oversight log
1376 - $logtype = ( ($nbitfield | $obitfield) & Revision::DELETED_RESTRICTED ) ? 'oversight' : 'delete';
1377 - $log = new LogPage( $logtype );
1378 - // FIXME: do this better
1379 - if( $param=='logid' ) {
1380 - $params = array( implode( ',', $items) );
1381 - $reason = wfMsgExt('logdelete-logaction', array('parsemag'), $count, $nbitfield );
1382 - if($comment) $reason .= ": $comment";
1383 - $log->addEntry( 'event', $title, $reason, $params );
1384 - } else {
1385 - // Add params for effected page and ids
1386 - $params = array( $target->getPrefixedText(), $param, implode( ',', $items) );
1387 - $reason = wfMsgExt('revdelete-logaction', array('parsemag'), $count, $nbitfield );
1388 - if($comment) $reason .= ": $comment";
1389 - $log->addEntry( 'revision', $title, $reason, $params );
1390 - }
 268+ function updateLog( $title, $count, $bitfield, $comment ) {
 269+ $log = new LogPage( 'delete' );
 270+ $reason = "changed $count revisions to $bitfield";
 271+ $reason .= ": $comment";
 272+ $log->addEntry( 'revision', $title, $reason );
1391273 }
1392274 }
 275+
 276+
Index: trunk/phase3/includes/EditPage.php
@@ -982,13 +982,9 @@
983983 }
984984 if ( isset( $this->mArticle ) && isset( $this->mArticle->mRevision ) ) {
985985 // Let sysop know that this will make private content public if saved
986 -
987 - if( !$this->mArticle->mRevision->userCan( Revision::DELETED_TEXT ) ) {
988 - $wgOut->addWikiText( wfMsg( 'rev-deleted-text-permission' ) );
989 - } else if( $this->mArticle->mRevision->isDeleted( Revision::DELETED_TEXT ) ) {
 986+ if( $this->mArticle->mRevision->isDeleted( Revision::DELETED_TEXT ) ) {
990987 $wgOut->addWikiText( wfMsg( 'rev-deleted-text-view' ) );
991988 }
992 -
993989 if( !$this->mArticle->mRevision->isCurrent() ) {
994990 $this->mArticle->setOldSubtitle( $this->mArticle->mRevision->getId() );
995991 $wgOut->addWikiText( wfMsg( 'editingold' ) );
Index: trunk/phase3/includes/FileDeleteForm.php
@@ -46,14 +46,8 @@
4747 return;
4848 }
4949
50 - # Use revision delete
51 - # $this->oldimage = $wgRequest->getText( 'oldimage', false );
52 -
53 - $this->oldimage = false;
 50+ $this->oldimage = $wgRequest->getText( 'oldimage', false );
5451 $token = $wgRequest->getText( 'wpEditToken' );
55 - # Flag to hide all contents of the archived revisions
56 - $suppress = $wgRequest->getVal( 'wpSuppress' ) && $wgUser->isAllowed('deleterevision');
57 -
5852 if( $this->oldimage && !$this->isValidOldSpec() ) {
5953 $wgOut->showUnexpectedValueError( 'oldimage', htmlspecialchars( $this->oldimage ) );
6054 return;
@@ -71,7 +65,7 @@
7266 if( $wgRequest->wasPosted() && $wgUser->matchEditToken( $token, $this->oldimage ) ) {
7367 $comment = $wgRequest->getText( 'wpReason' );
7468 if( $this->oldimage ) {
75 - $status = $this->file->deleteOld( $this->oldimage, $comment, $suppress );
 69+ $status = $this->file->deleteOld( $this->oldimage, $comment );
7670 if( $status->ok ) {
7771 // Need to do a log item
7872 $log = new LogPage( 'delete' );
@@ -81,7 +75,7 @@
8276 $log->addEntry( 'delete', $this->title, $logComment );
8377 }
8478 } else {
85 - $status = $this->file->delete( $comment, $suppress );
 79+ $status = $this->file->delete( $comment );
8680 if( $status->ok ) {
8781 // Need to delete the associated article
8882 $article = new Article( $this->title );
Index: trunk/phase3/includes/Setup.php
@@ -57,10 +57,8 @@
5858 if ( empty( $wgFileStore['deleted']['directory'] ) ) {
5959 $wgFileStore['deleted']['directory'] = "{$wgUploadDirectory}/deleted";
6060 }
61 -if ( empty( $wgFileStore['hidden']['directory'] ) ) {
62 - $wgFileStore['hidden']['directory'] = "{$wgUploadDirectory}/hidden";
63 -}
6461
 62+
6563 /**
6664 * Initialise $wgLocalFileRepo from backwards-compatible settings
6765 */
@@ -75,9 +73,7 @@
7674 'transformVia404' => !$wgGenerateThumbnailOnParse,
7775 'initialCapital' => $wgCapitalLinks,
7876 'deletedDir' => $wgFileStore['deleted']['directory'],
79 - 'deletedHashLevels' => $wgFileStore['deleted']['hash'],
80 - 'hiddenDir' => $wgFileStore['hidden']['directory'],
81 - 'hiddenHashLevels' => $wgFileStore['hidden']['hash']
 77+ 'deletedHashLevels' => $wgFileStore['deleted']['hash']
8278 );
8379 }
8480 /**
Index: trunk/phase3/includes/SpecialWatchlist.php
@@ -161,8 +161,7 @@
162162 $andLatest='';
163163 $limitWatchlist = 'LIMIT ' . intval( $wgUser->getOption( 'wllimit' ) );
164164 } else {
165 - # Top log Ids for a page are not stored
166 - $andLatest = 'AND (rc_this_oldid=page_latest OR rc_type=' . RC_LOG . ') ';
 165+ $andLatest= 'AND rc_this_oldid=page_latest';
167166 $limitWatchlist = '';
168167 }
169168
@@ -365,4 +364,4 @@
366365 $count = floor( $count / 2 );
367366
368367 return( $count );
369 -}
 368+}
\ No newline at end of file
Index: trunk/phase3/includes/ChangesList.php
@@ -75,7 +75,7 @@
7676 : $nothing;
7777 $f .= $bot ? '<span class="bot">' . $this->message['boteditletter'] . '</span>' : $nothing;
7878 $f .= $patrolled ? '<span class="unpatrolled">!</span>' : $nothing;
79 - return "<tt>$f</tt>";
 79+ return $f;
8080 }
8181
8282 /**
@@ -101,32 +101,6 @@
102102 }
103103 }
104104
105 - /**
106 - * int $field one of DELETED_* bitfield constants
107 - * @return bool
108 - */
109 - function isDeleted( $rc, $field ) {
110 - return ($rc->mAttribs['rc_deleted'] & $field) == $field;
111 - }
112 -
113 - /**
114 - * Determine if the current user is allowed to view a particular
115 - * field of this revision, if it's marked as deleted.
116 - * @param int $field
117 - * @return bool
118 - */
119 - function userCan( $rc, $field ) {
120 - if( ( $rc->mAttribs['rc_deleted'] & $field ) == $field ) {
121 - global $wgUser;
122 - $permission = ( $rc->mAttribs['rc_deleted'] & Revision::DELETED_RESTRICTED ) == Revision::DELETED_RESTRICTED
123 - ? 'hiderevision'
124 - : 'deleterevision';
125 - wfDebug( "Checking for $permission due to $field match on $rc->mAttribs['rc_deleted']\n" );
126 - return $wgUser->isAllowed( $permission );
127 - } else {
128 - return true;
129 - }
130 - }
131105
132106 function insertMove( &$s, $rc ) {
133107 # Diff
@@ -162,12 +136,11 @@
163137 $s .= '(' . $this->skin->makeKnownLinkObj($title, $logname ) . ')';
164138 }
165139
 140+
166141 function insertDiffHist(&$s, &$rc, $unpatrolled) {
167142 # Diff link
168 - if( !$this->userCan($rc,Revision::DELETED_TEXT) ) {
 143+ if( $rc->mAttribs['rc_type'] == RC_NEW || $rc->mAttribs['rc_type'] == RC_LOG ) {
169144 $diffLink = $this->message['diff'];
170 - } else if( $rc->mAttribs['rc_type'] == RC_NEW || $rc->mAttribs['rc_type'] == RC_LOG ) {
171 - $diffLink = $this->message['diff'];
172145 } else {
173146 $rcidparam = $unpatrolled
174147 ? array( 'rcid' => $rc->mAttribs['rc_id'] )
@@ -197,12 +170,7 @@
198171 $params = ( $unpatrolled && $rc->mAttribs['rc_type'] == RC_NEW )
199172 ? 'rcid='.$rc->mAttribs['rc_id']
200173 : '';
201 - if( $this->isDeleted($rc,Revision::DELETED_TEXT) ) {
202 - $articlelink = $this->skin->makeKnownLinkObj( $rc->getTitle(), '', $params );
203 - $articlelink = '<span class="history-deleted">'.$articlelink.'</span>';
204 - } else {
205 - $articlelink = ' '. $this->skin->makeKnownLinkObj( $rc->getTitle(), '', $params );
206 - }
 174+ $articlelink = ' '. $this->skin->makeKnownLinkObj( $rc->getTitle(), '', $params );
207175 if( $watched )
208176 $articlelink = "<strong class=\"mw-watched\">{$articlelink}</strong>";
209177 global $wgContLang;
@@ -219,38 +187,15 @@
220188
221189 /** Insert links to user page, user talk page and eventually a blocking link */
222190 function insertUserRelatedLinks(&$s, &$rc) {
223 - if ( $this->isDeleted($rc,Revision::DELETED_USER) ) {
224 - $s .= ' <span class="history-deleted">' . wfMsgHtml('rev-deleted-user') . '</span>';
225 - } else {
226 - $s .= $this->skin->userLink( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] );
227 - $s .= $this->skin->userToolLinks( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] );
228 - }
 191+ $s .= $this->skin->userLink( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] );
 192+ $s .= $this->skin->userToolLinks( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] );
229193 }
230194
231 - /** insert a formatted action */
232 - function insertAction(&$s, &$rc) {
233 - # Add comment
234 - if( $rc->mAttribs['rc_type'] == RC_LOG ) {
235 - // log action
236 - if ( $this->isDeleted($rc,LogViewer::DELETED_ACTION) ) {
237 - $s .= ' <span class="history-deleted">' . wfMsgHtml('rev-deleted-event') . '</span>';
238 - } else {
239 - $s .= ' ' . LogPage::actionText( $rc->mAttribs['rc_log_type'], $rc->mAttribs['rc_log_action'],
240 - $rc->getTitle(), $this->skin, LogPage::extractParams($rc->mAttribs['rc_params']), true, true );
241 - }
242 - }
243 - }
244 -
245195 /** insert a formatted comment */
246196 function insertComment(&$s, &$rc) {
247197 # Add comment
248198 if( $rc->mAttribs['rc_type'] != RC_MOVE && $rc->mAttribs['rc_type'] != RC_MOVE_OVER_REDIRECT ) {
249 - // log comment
250 - if ( $this->isDeleted($rc,Revision::DELETED_COMMENT) ) {
251 - $s .= ' <span class="history-deleted">' . wfMsgHtml('rev-deleted-comment') . '</span>';
252 - } else {
253 - $s .= $this->skin->commentBlock( $rc->mAttribs['rc_comment'], $rc->getTitle() );
254 - }
 199+ $s .= $this->skin->commentBlock( $rc->mAttribs['rc_comment'], $rc->getTitle() );
255200 }
256201 }
257202
@@ -306,22 +251,18 @@
307252
308253 $s .= '<li>';
309254
310 - // Moved pages
 255+ // moved pages
311256 if( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
312257 $this->insertMove( $s, $rc );
313 - // Log entries
314 - } elseif( $rc_log_type !='' ) {
315 - $logtitle = Title::newFromText( "Log/$rc_log_type", NS_SPECIAL );
316 - $this->insertLog( $s, $logtitle, $rc_log_type );
317 - // Log entries (old format) or log targets, and special pages
318 - } elseif( $rc_namespace == NS_SPECIAL ) {
 258+ // log entries
 259+ } elseif ( $rc_namespace == NS_SPECIAL ) {
319260 list( $specialName, $specialSubpage ) = SpecialPage::resolveAliasWithSubpage( $rc_title );
320261 if ( $specialName == 'Log' ) {
321262 $this->insertLog( $s, $rc->getTitle(), $specialSubpage );
322263 } else {
323264 wfDebug( "Unexpected special page in recentchanges\n" );
324265 }
325 - // Log entries
 266+ // all other stuff
326267 } else {
327268 wfProfileIn($fname.'-page');
328269
@@ -343,16 +284,10 @@
344285 }
345286
346287 $this->insertUserRelatedLinks($s,$rc);
347 - $this->insertAction($s, $rc);
348288 $this->insertComment($s, $rc);
349 -
350 - # Mark revision as deleted
351 - if ( !$rc_log_type && $this->isDeleted($rc,Revision::DELETED_TEXT) )
352 - $s .= ' <tt>' . wfMsgHtml( 'deletedrev' ) . '</tt>';
353 - if($rc->numberofWatchingusers > 0) {
354 - $s .= ' ' . wfMsg('number_of_watching_users_RCview', $wgContLang->formatNum($rc->numberofWatchingusers));
355 - }
356289
 290+ $s .= rtrim(' ' . $this->numberofWatchingusers($rc->numberofWatchingusers));
 291+
357292 $s .= "</li>\n";
358293
359294 wfProfileOut( $fname.'-rest' );
@@ -399,14 +334,12 @@
400335 $rc->unpatrolled = false;
401336 }
402337
403 - $showrev=true;
404338 # Make article link
405339 if( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
406340 $msg = ( $rc_type == RC_MOVE ) ? "1movedto2" : "1movedto2_redir";
407341 $clink = wfMsg( $msg, $this->skin->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
408342 $this->skin->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
409 - } else if( $rc_namespace == NS_SPECIAL ) {
410 - // Log entries (old format) and special pages
 343+ } elseif( $rc_namespace == NS_SPECIAL ) {
411344 list( $specialName, $logtype ) = SpecialPage::resolveAliasWithSubpage( $rc_title );
412345 if ( $specialName == 'Log' ) {
413346 # Log updates, etc
@@ -416,16 +349,7 @@
417350 wfDebug( "Unexpected special page in recentchanges\n" );
418351 $clink = '';
419352 }
420 - } elseif ( $rc_log_type !='' ) {
421 - // Log entries
422 - $logtitle = Title::newFromText( "Log/$rc_log_type", NS_SPECIAL );
423 - $logname = LogPage::logName( $rc_log_type );
424 - $clink = '(' . $this->skin->makeKnownLinkObj($logtitle, $logname ) . ')';
425 - } if ( $this->isDeleted($rc,Revision::DELETED_TEXT) ) {
426 - $clink = '<span class="history-deleted">' . $this->skin->makeKnownLinkObj( $rc->getTitle(), '' ) . '</span>';
427 - if ( !ChangesList::userCan($rc,Revision::DELETED_TEXT) )
428 - $showrev=false;
429 - } else if( $rc->unpatrolled && $rc_type == RC_NEW ) {
 353+ } elseif( $rc->unpatrolled && $rc_type == RC_NEW ) {
430354 # Unpatrolled new page, give rc_id in query
431355 $clink = $this->skin->makeKnownLinkObj( $rc->getTitle(), '', "rcid={$rc_id}" );
432356 } else {
@@ -448,10 +372,7 @@
449373 $querydiff = $curIdEq."&diff=$rc_this_oldid&oldid=$rc_last_oldid$rcIdQuery";
450374 $aprops = ' tabindex="'.$baseRC->counter.'"';
451375 $curLink = $this->skin->makeKnownLinkObj( $rc->getTitle(), $this->message['cur'], $querycur, '' ,'', $aprops );
452 - if ( !$showrev ) {
453 - $curLink = $this->message['cur'];
454 - $diffLink = $this->message['diff'];
455 - } else if( $rc_type == RC_NEW || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
 376+ if( $rc_type == RC_NEW || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
456377 if( $rc_type != RC_NEW ) {
457378 $curLink = $this->message['cur'];
458379 }
@@ -461,27 +382,21 @@
462383 }
463384
464385 # Make "last" link
465 - if ( !$showrev ) {
466 - $lastLink = $this->message['last'];
467 - } else if( $rc_last_oldid == 0 || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
 386+ if( $rc_last_oldid == 0 || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
468387 $lastLink = $this->message['last'];
469388 } else {
470389 $lastLink = $this->skin->makeKnownLinkObj( $rc->getTitle(), $this->message['last'],
471 - $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid . $rcIdQuery );
 390+ $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid . $rcIdQuery );
472391 }
473 -
474 - # Make user links
475 - if ( $this->isDeleted($rc,Revision::DELETED_USER) ) {
476 - $rc->userlink = ' <span class="history-deleted">' . wfMsgHtml('rev-deleted-user') . '</span>';
477 - } else {
478 - $rc->userlink = $this->skin->userLink( $rc_user, $rc_user_text );
479 - $rc->usertalklink = $this->skin->userToolLinks( $rc_user, $rc_user_text );
480 - }
481392
 393+ $rc->userlink = $this->skin->userLink( $rc_user, $rc_user_text );
 394+
482395 $rc->lastlink = $lastLink;
483396 $rc->curlink = $curLink;
484397 $rc->difflink = $diffLink;
485398
 399+ $rc->usertalklink = $this->skin->userToolLinks( $rc_user, $rc_user_text );
 400+
486401 # Put accumulated information into the cache, for later display
487402 # Page moves go on their own line
488403 $title = $rc->getTitle();
@@ -503,11 +418,10 @@
504419 */
505420 function recentChangesBlockGroup( $block ) {
506421 global $wgLang, $wgContLang, $wgRCShowChangedSize;
507 - $r = '<table cellpadding="0" cellspacing="0"><tr>';
 422+ $r = '';
508423
509424 # Collate list of users
510425 $isnew = false;
511 - $namehidden = true;
512426 $unpatrolled = false;
513427 $userlinks = array();
514428 foreach( $block as $rcObj ) {
@@ -515,11 +429,6 @@
516430 if( $rcObj->mAttribs['rc_new'] ) {
517431 $isnew = true;
518432 }
519 - // if all log actions to this page were hidden, then don't
520 - // give the name of the affected page for this block
521 - if( !($rcObj->mAttribs['rc_deleted'] & LogViewer::DELETED_ACTION) ) {
522 - $namehidden = false;
523 - }
524433 $u = $rcObj->userlink;
525434 if( !isset( $userlinks[$u] ) ) {
526435 $userlinks[$u] = 0;
@@ -553,25 +462,24 @@
554463 $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')";
555464 $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'">' . $this->sideArrow() . '</a></span>';
556465 $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'">' . $this->downArrow() . '</a></span>';
557 - $r .= '<td valign="top">'.$tl;
 466+ $r .= $tl;
558467
559468 # Main line
560 - $r .= ' '.$this->recentChangesFlags( $isnew, false, $unpatrolled, '&nbsp;', $bot );
 469+ $r .= '<tt>';
 470+ $r .= $this->recentChangesFlags( $isnew, false, $unpatrolled, '&nbsp;', $bot );
561471
562472 # Timestamp
563 - $r .= '&nbsp;'.$block[0]->timestamp.'&nbsp;&nbsp;</td><td>';
 473+ $r .= ' '.$block[0]->timestamp.' </tt>';
564474
565475 # Article link
566 - if ( $namehidden )
567 - $r .= ' <span class="history-deleted">' . wfMsgHtml('rev-deleted-event') . '</span>';
568 - else
569 - $r .= $this->maybeWatchedLink( $block[0]->link, $block[0]->watched );
 476+ $r .= $this->maybeWatchedLink( $block[0]->link, $block[0]->watched );
570477 $r .= $wgContLang->getDirMark();
571478
572479 $curIdEq = 'curid=' . $block[0]->mAttribs['rc_cur_id'];
573480 $currentRevision = $block[0]->mAttribs['rc_this_oldid'];
574481 if( $block[0]->mAttribs['rc_type'] != RC_LOG ) {
575482 # Changes
 483+
576484 $n = count($block);
577485 static $nchanges = array();
578486 if ( !isset( $nchanges[$n] ) ) {
@@ -581,25 +489,25 @@
582490
583491 $r .= ' (';
584492
585 - if( !ChangesList::userCan($rcObj,Revision::DELETED_TEXT) ) {
586 - $r .= $nchanges[$n];
587 - } else if( $isnew ) {
 493+ if( $isnew ) {
588494 $r .= $nchanges[$n];
589495 } else {
590496 $r .= $this->skin->makeKnownLinkObj( $block[0]->getTitle(),
591497 $nchanges[$n], $curIdEq."&diff=$currentRevision&oldid=$oldid" );
592498 }
593499
 500+ $r .= ') . . ';
 501+
594502 if( $wgRCShowChangedSize ) {
595503 # Character difference
596504 $chardiff = $rcObj->getCharacterDifference( $block[ count( $block ) - 1 ]->mAttribs['rc_old_len'],
597505 $block[0]->mAttribs['rc_new_len'] );
598506 if( $chardiff == '' ) {
599 - $r .= ') ';
 507+ $r .= ' (';
600508 } else {
601509 $r .= ' ' . $chardiff. ' . . ';
602510 }
603 - }
 511+ }
604512
605513 # History
606514 $r .= '(' . $this->skin->makeKnownLinkObj( $block[0]->getTitle(),
@@ -608,70 +516,51 @@
609517 }
610518
611519 $r .= $users;
612 - $r .=$this->numberofWatchingusers($block[0]->numberofWatchingusers);
613 -
614 - $r .= "</td></tr></table>\n";
615520
 521+ $r .= $this->numberofWatchingusers($block[0]->numberofWatchingusers);
 522+ $r .= "<br />\n";
 523+
616524 # Sub-entries
617 - $r .= '<div id="'.$rci.'" style="display:none; font-size:95%;"><table cellpadding="0" cellspacing="0">';
 525+ $r .= '<div id="'.$rci.'" style="display:none">';
618526 foreach( $block as $rcObj ) {
619527 # Get rc_xxxx variables
620528 // FIXME: Would be good to replace this extract() call with something that explicitly initializes local variables.
621529 extract( $rcObj->mAttribs );
622530
623 - #$r .= '<tr><td valign="top">'.$this->spacerArrow();
624 - $r .= '<tr><td valign="top">'.$this->spacerIndent();
625 - $r .= '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
 531+ $r .= $this->spacerArrow();
 532+ $r .= '<tt>&nbsp; &nbsp; &nbsp; &nbsp;';
626533 $r .= $this->recentChangesFlags( $rc_new, $rc_minor, $rcObj->unpatrolled, '&nbsp;', $rc_bot );
627 - $r .= '&nbsp;&nbsp;</td><td valign="top">';
 534+ $r .= '&nbsp;</tt>';
628535
629536 $o = '';
630537 if( $rc_this_oldid != 0 ) {
631538 $o = 'oldid='.$rc_this_oldid;
632539 }
633 - # Revision link
634540 if( $rc_type == RC_LOG ) {
635 - $link = $rcObj->timestamp.' ';
636 - } else if( !ChangesList::userCan($rcObj,Revision::DELETED_TEXT) ) {
637 - $link = '<span class="history-deleted">'.$rcObj->timestamp.'</span> ';
 541+ $link = $rcObj->timestamp;
638542 } else {
639543 $link = $this->skin->makeKnownLinkObj( $rcObj->getTitle(), $rcObj->timestamp, $curIdEq.'&'.$o );
640 - if( $this->isDeleted($rcObj,Revision::DELETED_TEXT) )
641 - $link = '<span class="history-deleted">'.$link.'</span> ';
642544 }
 545+ $link = '<tt>'.$link.'</tt>';
 546+
643547 $r .= $link;
644 -
645 - if ( !$rc_log_type ) {
646 - $r .= ' (';
647 - $r .= $rcObj->curlink;
648 - $r .= '; ';
649 - $r .= $rcObj->lastlink;
650 - $r .= ')';
651 - } else {
652 - $logname = LogPage::logName( $rc_log_type );
653 - $logtitle = Title::newFromText( "Log/$rc_log_type", NS_SPECIAL );
654 - $r .= '(' . $this->skin->makeKnownLinkObj($logtitle, $logname ) . ')';
655 - }
656 - $r .= ' . . ';
 548+ $r .= ' (';
 549+ $r .= $rcObj->curlink;
 550+ $r .= '; ';
 551+ $r .= $rcObj->lastlink;
 552+ $r .= ') . . ';
657553
658554 # Character diff
659555 if( $wgRCShowChangedSize ) {
660556 $r .= ( $rcObj->getCharacterDifference() == '' ? '' : $rcObj->getCharacterDifference() . ' . . ' ) ;
661557 }
662 - # User links
 558+
663559 $r .= $rcObj->userlink;
664560 $r .= $rcObj->usertalklink;
665 - // log action
666 - parent::insertAction($r, $rcObj);
667 - // log comment
668 - parent::insertComment($r, $rcObj);
669 - # Mark revision as deleted
670 - if ( !$rc_log_type && $this->isDeleted($rcObj,Revision::DELETED_TEXT) )
671 - $s .= ' <tt>' . wfMsgHtml( 'deletedrev' ) . '</tt>';
672 -
673 - $r .= "</td></tr>\n";
 561+ $r .= $this->skin->commentBlock( $rc_comment, $rcObj->getTitle() );
 562+ $r .= "<br />\n";
674563 }
675 - $r .= "</table></div>\n";
 564+ $r .= "</div>\n";
676565
677566 $this->rcCacheIndex++;
678567 return $r;
@@ -728,23 +617,8 @@
729618 * @access private
730619 */
731620 function spacerArrow() {
732 - //FIXME: problems with FF 1.5x
733621 return $this->arrow( '', ' ' );
734622 }
735 -
736 - /**
737 - * Generate HTML for the equivilant of a spacer image for tables
738 - * @return string HTML <td> tag
739 - * @access private
740 - */
741 - function spacerColumn() {
742 - return '<td width="12"></td>';
743 - }
744 -
745 - // Adds a few spaces
746 - function spacerIndent() {
747 - return '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
748 - }
749623
750624 /**
751625 * Enhanced RC ungrouped line.
@@ -758,64 +632,46 @@
759633 extract( $rcObj->mAttribs );
760634 $curIdEq = 'curid='.$rc_cur_id;
761635
762 - $r = '<table cellspacing="0" cellpadding="0"><tr><td>';
 636+ $r = '';
763637
764 - # spacerArrow() causes issues in FF
765 - $r .= $this->spacerColumn();
766 - $r .= '<td valign="top">';
767 -
 638+ # Spacer image
 639+ $r .= $this->spacerArrow();
 640+
768641 # Flag and Timestamp
 642+ $r .= '<tt>';
 643+
769644 if( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
770 - $r .= '&nbsp;&nbsp;&nbsp;&nbsp;';
 645+ $r .= '&nbsp;&nbsp;&nbsp;';
771646 } else {
772 - $r .= '&nbsp;'.$this->recentChangesFlags( $rc_type == RC_NEW, $rc_minor, $rcObj->unpatrolled, '&nbsp;', $rc_bot );
 647+ $r .= $this->recentChangesFlags( $rc_type == RC_NEW, $rc_minor, $rcObj->unpatrolled, '&nbsp;', $rc_bot );
773648 }
774 - $r .= '&nbsp;'.$rcObj->timestamp.'&nbsp;&nbsp;</td><td>';
775 -
 649+ $r .= ' '.$rcObj->timestamp.' </tt>';
 650+
776651 # Article link
777 - if ( $rc_log_type !='' ) {
778 - $logtitle = Title::newFromText( "Log/$rc_log_type", NS_SPECIAL );
779 - $logname = LogPage::logName( $rc_log_type );
780 - $r .= '(' . $this->skin->makeKnownLinkObj($logtitle, $logname ) . ')';
781 - // All other stuff
782 - } else {
783 - $r .= $this->maybeWatchedLink( $rcObj->link, $rcObj->watched );
784 - }
785 - if ( $rc_type != RC_LOG ) {
786 - # Diff
787 - $r .= ' ('. $rcObj->difflink .'; ';
788 - # Hist
789 - $r .= $this->skin->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' ) . ')';
790 - }
791 - $r .= ' . . ';
792 -
 652+ $r .= $this->maybeWatchedLink( $rcObj->link, $rcObj->watched );
 653+
 654+ # Diff
 655+ $r .= ' ('. $rcObj->difflink .'; ';
 656+
 657+ # Hist
 658+ $r .= $this->skin->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' ) . ') . . ';
 659+
793660 # Character diff
794661 if( $wgRCShowChangedSize ) {
795662 $r .= ( $rcObj->getCharacterDifference() == '' ? '' : '&nbsp;' . $rcObj->getCharacterDifference() . ' . . ' ) ;
796663 }
797664
798665 # User/talk
799 - $r .= ' '.$rcObj->userlink . $rcObj->usertalklink;
 666+ $r .= $rcObj->userlink . $rcObj->usertalklink;
800667
801668 # Comment
802669 if( $rc_type != RC_MOVE && $rc_type != RC_MOVE_OVER_REDIRECT ) {
803 - // log action
804 - if ( $this->isDeleted($rcObj,LogViewer::DELETED_ACTION) ) {
805 - $r .= ' <span class="history-deleted">' . wfMsgHtml('rev-deleted-event') . '</span>';
806 - } else {
807 - $r .= ' ' . LogPage::actionText( $rc_log_type, $rc_log_action, $rcObj->getTitle(), $this->skin, LogPage::extractParams($rc_params), true, true );
808 - }
809 - // log comment
810 - if ( $this->isDeleted($rcObj,LogViewer::DELETED_COMMENT) ) {
811 - $r .= ' <span class="history-deleted">' . wfMsg('rev-deleted-comment') . '</span>';
812 - } else {
813 - $r .= $this->skin->commentBlock( $rc_comment, $rcObj->getTitle() );
814 - }
 670+ $r .= $this->skin->commentBlock( $rc_comment, $rcObj->getTitle() );
815671 }
816672
817673 $r .= $this->numberofWatchingusers($rcObj->numberofWatchingusers);
818674
819 - $r .= "</td></tr></table>\n";
 675+ $r .= "<br />\n";
820676 return $r;
821677 }
822678
Index: trunk/phase3/includes/Article.php
@@ -390,7 +390,6 @@
391391 // We should instead work with the Revision object when we need it...
392392 $this->mContent = $revision->userCan( Revision::DELETED_TEXT ) ? $revision->getRawText() : "";
393393 //$this->mContent = $revision->getText();
394 - $this->mContent = $revision->revText(); // Loads if user is allowed
395394
396395 $this->mUser = $revision->getUser();
397396 $this->mUserText = $revision->getUserText();
@@ -1070,6 +1069,7 @@
10711070 $result = $dbw->affectedRows() != 0;
10721071
10731072 if ($result) {
 1073+ // FIXME: Should the result from updateRedirectOn() be returned instead?
10741074 $this->updateRedirectOn( $dbw, $rt, $lastRevIsRedirect );
10751075 }
10761076
@@ -1494,7 +1494,6 @@
14951495 *
14961496 * @param boolean $noRedir Add redirect=no
14971497 * @param string $sectionAnchor section to redirect to, including "#"
1498 - * @param string $extraq, extra query params
14991498 */
15001499 function doRedirect( $noRedir = false, $sectionAnchor = '', $extraq = '' ) {
15011500 global $wgOut;
@@ -1690,7 +1689,7 @@
16911690 * @return bool true on success
16921691 */
16931692 function updateRestrictions( $limit = array(), $reason = '', $cascade = 0, $expiry = null ) {
1694 - global $wgUser, $wgRestrictionTypes, $wgContLang, $wgGroupPermissions;
 1693+ global $wgUser, $wgRestrictionTypes, $wgContLang;
16951694
16961695 $id = $this->mTitle->getArticleID();
16971696 if( !$wgUser->isAllowed( 'protect' ) || wfReadOnly() || $id == 0 ) {
@@ -1720,6 +1719,7 @@
17211720
17221721 # If nothing's changed, do nothing
17231722 if( $changed ) {
 1723+ global $wgGroupPermissions;
17241724 if( wfRunHooks( 'ArticleProtect', array( &$this, &$wgUser, $limit, $reason ) ) ) {
17251725
17261726 $dbw = wfGetDB( DB_MASTER );
@@ -1832,8 +1832,6 @@
18331833 $confirm = $wgRequest->wasPosted() &&
18341834 $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) );
18351835 $reason = $wgRequest->getText( 'wpReason' );
1836 - # Flag to hide all contents of the archived revisions
1837 - $suppress = $wgRequest->getVal( 'wpSuppress' ) && $wgUser->isAllowed('deleterevision');
18381836
18391837 # This code desperately needs to be totally rewritten
18401838
@@ -1858,7 +1856,7 @@
18591857 }
18601858
18611859 if( $confirm ) {
1862 - $this->doDelete( $reason, $suppress );
 1860+ $this->doDelete( $reason );
18631861 if( $wgRequest->getCheck( 'wpWatch' ) ) {
18641862 $this->doWatch();
18651863 } elseif( $this->mTitle->userIsWatching() ) {
@@ -2004,14 +2002,7 @@
20052003 $delcom = htmlspecialchars( wfMsg( 'deletecomment' ) );
20062004 $token = htmlspecialchars( $wgUser->editToken() );
20072005 $watch = Xml::checkLabel( wfMsg( 'watchthis' ), 'wpWatch', 'wpWatch', $wgUser->getBoolOption( 'watchdeletion' ) || $this->mTitle->userIsWatching(), array( 'tabindex' => '2' ) );
2008 - if ( $wgUser->isAllowed( 'deleterevision' ) ) {
2009 - $supress = "<tr><td>&nbsp;</td><td>";
2010 - $supress .= Xml::checkLabel( wfMsg( 'revdelete-suppress' ), 'wpSuppress', 'wpSuppress', false, array( 'tabindex' => '2' ) );
2011 - $supress .= "</td></tr>";
2012 - } else {
2013 - $supress = '';
2014 - }
2015 -
 2006+
20162007 $wgOut->addHTML( "
20172008 <form id='deleteconfirm' method='post' action=\"{$formaction}\">
20182009 <table border='0'>
@@ -2023,7 +2014,6 @@
20242015 <input type='text' size='60' name='wpReason' id='wpReason' value=\"" . htmlspecialchars( $reason ) . "\" tabindex=\"1\" />
20252016 </td>
20262017 </tr>
2027 - $supress
20282018 <tr>
20292019 <td>&nbsp;</td>
20302020 <td>$watch</td>
@@ -2061,12 +2051,12 @@
20622052 /**
20632053 * Perform a deletion and output success or failure messages
20642054 */
2065 - function doDelete( $reason, $suppress = false ) {
 2055+ function doDelete( $reason ) {
20662056 global $wgOut, $wgUser;
20672057 wfDebug( __METHOD__."\n" );
20682058
20692059 if (wfRunHooks('ArticleDelete', array(&$this, &$wgUser, &$reason))) {
2070 - if ( $this->doDeleteArticle( $reason, $suppress ) ) {
 2060+ if ( $this->doDeleteArticle( $reason ) ) {
20712061 $deleted = wfEscapeWikiText( $this->mTitle->getPrefixedText() );
20722062
20732063 $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) );
@@ -2079,7 +2069,7 @@
20802070 $wgOut->returnToMain( false );
20812071 wfRunHooks('ArticleDeleteComplete', array(&$this, &$wgUser, $reason));
20822072 } else {
2083 - $wgOut->showFatalError( wfMsg( 'cannotdelete' ).'<br/>'.wfMsg('cannotdelete-merge') );
 2073+ $wgOut->showFatalError( wfMsg( 'cannotdelete' ) );
20842074 }
20852075 }
20862076 }
@@ -2089,7 +2079,7 @@
20902080 * Deletes the article with database consistency, writes logs, purges caches
20912081 * Returns success
20922082 */
2093 - function doDeleteArticle( $reason, $suppress = false ) {
 2083+ function doDeleteArticle( $reason ) {
20942084 global $wgUseSquid, $wgDeferredUpdateList;
20952085 global $wgUseTrackbacks;
20962086
@@ -2103,30 +2093,10 @@
21042094 if ( $t == '' || $id == 0 ) {
21052095 return false;
21062096 }
2107 - // Do not fuck up histories by merging them in annoying, unrevertable ways
2108 - // This page id should match any deleted ones (excepting NULL values)
2109 - $otherpages = $dbw->selectField( 'archive', 'COUNT(*)',
2110 - array('ar_namespace' => $ns, 'ar_title' => $t,
2111 - 'ar_page_id IS NOT NULL', "ar_page_id != $id" ),
2112 - __METHOD__ );
2113 - if( $otherpages )
2114 - return false;
21152097
21162098 $u = new SiteStatsUpdate( 0, 1, -(int)$this->isCountable( $this->getContent() ), -1 );
21172099 array_push( $wgDeferredUpdateList, $u );
21182100
2119 - // Bitfields to further supress the content
2120 - if ( $suppress ) {
2121 - $bitfield = 0;
2122 - // This should be 15...
2123 - $bitfield |= Revision::DELETED_TEXT;
2124 - $bitfield |= Revision::DELETED_COMMENT;
2125 - $bitfield |= Revision::DELETED_USER;
2126 - $bitfield |= Revision::DELETED_RESTRICTED;
2127 - } else {
2128 - $bitfield = 'rev_deleted';
2129 - }
2130 -
21312101 // For now, shunt the revision data into the archive table.
21322102 // Text is *not* removed from the text table; bulk storage
21332103 // is left intact to avoid breaking block-compression or
@@ -2152,7 +2122,6 @@
21532123 'ar_flags' => '\'\'', // MySQL's "strict mode"...
21542124 'ar_len' => 'rev_len',
21552125 'ar_page_id' => 'page_id',
2156 - 'ar_deleted' => $bitfield
21572126 ), array(
21582127 'page_id' => $id,
21592128 'page_id = rev_page'
@@ -2193,9 +2162,8 @@
21942163 # Clear caches
21952164 Article::onArticleDelete( $this->mTitle );
21962165
2197 - # Log the deletion, if the page was suppressed, log it at Oversight instead
2198 - $logtype = ($suppress) ? 'oversight' : 'delete';
2199 - $log = new LogPage( $logtype );
 2166+ # Log the deletion
 2167+ $log = new LogPage( 'delete' );
22002168 $log->addEntry( 'delete', $this->mTitle, $reason );
22012169
22022170 # Clear the cached article id so the interface doesn't act like we exist
@@ -2294,13 +2262,8 @@
22952263 );
22962264 }
22972265
2298 - $target = Revision::newFromId( $s->rev_id );
2299 - # Revision *must* be public and we don't well handle deleted edits on top
2300 - if ( $target->isDeleted(REVISION::DELETED_TEXT) ) {
2301 - $wgOut->setPageTitle( wfMsg('rollbackfailed') );
2302 - $wgOut->addHTML( wfMsg( 'missingarticle' ) );
2303 - }
23042266 # Get the edit summary
 2267+ $target = Revision::newFromId( $s->rev_id );
23052268 if( empty( $summary ) )
23062269 $summary = wfMsgForContent( 'revertpage', $target->getUserText(), $from );
23072270
@@ -2561,28 +2524,8 @@
25622525 ? wfMsg( 'diff' )
25632526 : $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'diff' ), 'diff=next&oldid='.$oldid );
25642527
2565 - $cdel='';
2566 - if( $wgUser->isAllowed( 'deleterevision' ) ) {
2567 - $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
2568 - if( $revision->isCurrent() ) {
2569 - // We don't handle top deleted edits too well
2570 - $cdel = wfMsgHtml('rev-delundel');
2571 - } else if( !$revision->userCan( Revision::DELETED_RESTRICTED ) ) {
2572 - // If revision was hidden from sysops
2573 - $cdel = wfMsgHtml('rev-delundel');
2574 - } else {
2575 - $cdel = $sk->makeKnownLinkObj( $revdel,
2576 - wfMsgHtml('rev-delundel'),
2577 - 'target=' . urlencode( $this->mTitle->getPrefixedDbkey() ) .
2578 - '&oldid=' . urlencode( $oldid ) );
2579 - // Bolden oversighted content
2580 - if( $revision->isDeleted( Revision::DELETED_RESTRICTED ) )
2581 - $cdel = "<strong>$cdel</strong>";
2582 - }
2583 - $cdel = "(<small>$cdel</small>) ";
2584 - }
2585 -
2586 - $userlinks = $sk->revUserTools( $revision, true );
 2528+ $userlinks = $sk->userLink( $revision->getUser(), $revision->getUserText() )
 2529+ . $sk->userToolLinks( $revision->getUser(), $revision->getUserText() );
25872530
25882531 $m = wfMsg( 'revision-info-current' );
25892532 $infomsg = $current && !wfEmptyMsg( 'revision-info-current', $m ) && $m != '-'
@@ -2590,8 +2533,7 @@
25912534 : 'revision-info';
25922535
25932536 $r = "\n\t\t\t\t<div id=\"mw-{$infomsg}\">" . wfMsg( $infomsg, $td, $userlinks ) . "</div>\n" .
2594 -
2595 - "\n\t\t\t\t<div id=\"mw-revision-nav\">" . $cdel . wfMsg( 'revision-nav', $prevdiff, $prevlink, $lnk, $curdiff, $nextlink, $nextdiff ) . "</div>\n\t\t\t";
 2537+ "\n\t\t\t\t<div id=\"mw-revision-nav\">" . wfMsg( 'revision-nav', $prevdiff, $prevlink, $lnk, $curdiff, $nextlink, $nextdiff ) . "</div>\n\t\t\t";
25962538 $wgOut->setSubtitle( $r );
25972539 }
25982540
Index: trunk/phase3/includes/Revision.php
@@ -794,7 +794,7 @@
795795 * @param bool $minor
796796 * @return Revision
797797 */
798 - static function newNullRevision( &$dbw, $pageId, $summary, $minor ) {
 798+ function newNullRevision( &$dbw, $pageId, $summary, $minor ) {
799799 $fname = 'Revision::newNullRevision';
800800 wfProfileIn( $fname );
801801
Index: trunk/phase3/includes/SpecialSpecialpages.php
@@ -16,13 +16,10 @@
1717 $sk = $wgUser->getSkin();
1818
1919 /** Pages available to all */
20 - wfSpecialSpecialpages_gen( SpecialPage::getRegularPages(), 'spheading', $sk, false );
 20+ wfSpecialSpecialpages_gen( SpecialPage::getRegularPages(), 'spheading', $sk );
2121
2222 /** Restricted special pages */
23 - wfSpecialSpecialpages_gen( SpecialPage::getRestrictedPages(), 'restrictedpheading', $sk, false );
24 -
25 - /** Restricted logs */
26 - wfSpecialSpecialpages_gen( SpecialPage::getRestrictedLogs(), 'restrictedlheading', $sk, true );
 23+ wfSpecialSpecialpages_gen( SpecialPage::getRestrictedPages(), 'restrictedpheading', $sk );
2724 }
2825
2926 /**
@@ -30,10 +27,9 @@
3128 * @param $pages the list of pages
3229 * @param $heading header to be used
3330 * @param $sk skin object ???
34 - * @param $islog, is this for a list of log types?
3531 */
36 -function wfSpecialSpecialpages_gen( $pages, $heading, $sk, $islog=false ) {
37 - global $wgOut, $wgUser, $wgSortSpecialPages;
 32+function wfSpecialSpecialpages_gen($pages,$heading,$sk) {
 33+ global $wgOut, $wgSortSpecialPages;
3834
3935 if( count( $pages ) == 0 ) {
4036 # Yeah, that was pointless. Thanks for coming.
@@ -42,13 +38,9 @@
4339
4440 /** Put them into a sortable array */
4541 $sortedPages = array();
46 - if( $islog ) {
47 - $sortedPages = $pages;
48 - } else {
49 - foreach ( $pages as $page ) {
50 - if ( $page->isListed() ) {
51 - $sortedPages[$page->getDescription()] = $page->getTitle();
52 - }
 42+ foreach ( $pages as $page ) {
 43+ if ( $page->isListed() ) {
 44+ $sortedPages[$page->getDescription()] = $page->getTitle();
5345 }
5446 }
5547
Index: trunk/phase3/includes/DifferenceEngine.php
@@ -48,7 +48,7 @@
4949 # Show diff between revision $old and the previous one.
5050 # Get previous one from DB.
5151 #
52 - $this->mNewid = intval($old);
 52+ $this->mNewid = intval($old);
5353
5454 $this->mOldid = $this->mTitle->getPreviousRevisionID( $this->mNewid );
5555
@@ -64,13 +64,6 @@
6565 $this->mNewid = 0;
6666 }
6767
68 - } else if( 'cur' === $new ) {
69 - # Show diff between revision $old and the current one.
70 - # Get previous one from DB.
71 - #
72 - $this->mNewid = $this->mTitle->getLatestRevID();
73 -
74 - $this->mOldid = intval($old);
7568 } else {
7669 $this->mOldid = intval($old);
7770 $this->mNewid = intval($new);
@@ -227,49 +220,14 @@
228221 $newminor = wfElement( 'span', array( 'class' => 'minor' ),
229222 wfMsg( 'minoreditletter') ) . ' ';
230223 }
231 -
232 - $rdel = ''; $ldel = '';
233 - if( $wgUser->isAllowed( 'deleterevision' ) ) {
234 - $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
235 - if( !$this->mOldRev->userCan( Revision::DELETED_RESTRICTED ) ) {
236 - // If revision was hidden from sysops
237 - $ldel = wfMsgHtml('rev-delundel');
238 - } else {
239 - $ldel = $sk->makeKnownLinkObj( $revdel,
240 - wfMsgHtml('rev-delundel'),
241 - 'target=' . urlencode( $this->mOldRev->mTitle->getPrefixedDbkey() ) .
242 - '&oldid=' . urlencode( $this->mOldRev->getId() ) );
243 - // Bolden oversighted content
244 - if( $this->mOldRev->isDeleted( Revision::DELETED_RESTRICTED ) )
245 - $ldel = "<strong>$ldel</strong>";
246 - }
247 - $ldel = "&nbsp;&nbsp;&nbsp;<tt>(<small>$ldel</small>)</tt> ";
248 - // We don't currently handle well changing the top revision's settings
249 - if( $this->mNewRev->isCurrent() ) {
250 - // If revision was hidden from sysops
251 - $rdel = wfMsgHtml('rev-delundel');
252 - } else if( !$this->mNewRev->userCan( Revision::DELETED_RESTRICTED ) ) {
253 - // If revision was hidden from sysops
254 - $rdel = wfMsgHtml('rev-delundel');
255 - } else {
256 - $rdel = $sk->makeKnownLinkObj( $revdel,
257 - wfMsgHtml('rev-delundel'),
258 - 'target=' . urlencode( $this->mNewRev->mTitle->getPrefixedDbkey() ) .
259 - '&oldid=' . urlencode( $this->mNewRev->getId() ) );
260 - // Bolden oversighted content
261 - if( $this->mNewRev->isDeleted( Revision::DELETED_RESTRICTED ) )
262 - $rdel = "<strong>$rdel</strong>";
263 - }
264 - $rdel = "&nbsp;&nbsp;&nbsp;<tt>(<small>$rdel</small>)</tt> ";
265 - }
266224
267 - $oldHeader = '<div id="mw-diff-otitle1"><strong>'.$this->mOldtitle.'</strong></div>' .
268 - '<div id="mw-diff-otitle2">' . $sk->revUserTools( $this->mOldRev, true ) . "</div>" .
269 - '<div id="mw-diff-otitle3">' . $oldminor . $sk->revComment( $this->mOldRev, !$diffOnly, true ) . $ldel . "</div>" .
270 - '<div id="mw-diff-otitle4">' . $prevlink .'</div>';
271 - $newHeader = '<div id="mw-diff-ntitle1"><strong>'.$this->mNewtitle.'</strong></div>' .
272 - '<div id="mw-diff-ntitle2">' . $sk->revUserTools( $this->mNewRev, true ) . " $rollback</div>" .
273 - '<div id="mw-diff-ntitle3">' . $newminor . $sk->revComment( $this->mNewRev, !$diffOnly, true ) . $rdel . "</div>" .
 225+ $oldHeader = '<div id="mw-diff-otitle1"><strong>' . $this->mOldtitle . '</strong></div>' .
 226+ '<div id="mw-diff-otitle2">' . $sk->revUserTools( $this->mOldRev ) . "</div>" .
 227+ '<div id="mw-diff-otitle3">' . $oldminor . $sk->revComment( $this->mOldRev, !$diffOnly ) . "</div>" .
 228+ '<div id="mw-diff-otitle4">' . $prevlink . '</div>';
 229+ $newHeader = '<div id="mw-diff-ntitle1"><strong>' .$this->mNewtitle . '</strong></div>' .
 230+ '<div id="mw-diff-ntitle2">' . $sk->revUserTools( $this->mNewRev ) . " $rollback</div>" .
 231+ '<div id="mw-diff-ntitle3">' . $newminor . $sk->revComment( $this->mNewRev, !$diffOnly ) . "</div>" .
274232 '<div id="mw-diff-ntitle4">' . $nextlink . $patrol . '</div>';
275233
276234 $this->showDiff( $oldHeader, $newHeader );
@@ -290,10 +248,8 @@
291249
292250 $wgOut->addHTML( "<hr /><h2>{$this->mPagetitle}</h2>\n" );
293251 #add deleted rev tag if needed
294 - if( !$this->mNewRev->userCan(Revision::DELETED_TEXT) ) {
 252+ if ( !$this->mNewRev->userCan(Revision::DELETED_TEXT) ) {
295253 $wgOut->addWikiText( wfMsg( 'rev-deleted-text-permission' ) );
296 - } else if( $this->mNewRev->isDeleted(Revision::DELETED_TEXT) ) {
297 - $wgOut->addWikiText( wfMsg( 'rev-deleted-text-view' ) );
298254 }
299255
300256 if( !$this->mNewRev->isCurrent() ) {
@@ -438,25 +394,20 @@
439395 } // don't try to load but save the result
440396 }
441397
442 - // Loadtext is permission safe, this just clears out the diff
 398+ #loadtext is permission safe, this just clears out the diff
443399 if ( !$this->loadText() ) {
444400 wfProfileOut( $fname );
445401 return false;
446402 } else if ( $this->mOldRev && !$this->mOldRev->userCan(Revision::DELETED_TEXT) ) {
447 - return '';
 403+ return '';
448404 } else if ( $this->mNewRev && !$this->mNewRev->userCan(Revision::DELETED_TEXT) ) {
449 - return '';
 405+ return '';
450406 }
451407
452408 $difftext = $this->generateDiffBody( $this->mOldtext, $this->mNewtext );
453409
454410 // Save to cache for 7 days
455 - // Only do this for public revs, otherwise an admin can view the diff and a non-admin can nab it!
456 - if ( $this->mOldRev && $this->mOldRev->isDeleted(Revision::DELETED_TEXT) ) {
457 - wfIncrStats( 'diff_uncacheable' );
458 - } else if ( $this->mNewRev && $this->mNewRev->isDeleted(Revision::DELETED_TEXT) ) {
459 - wfIncrStats( 'diff_uncacheable' );
460 - } else if ( $key !== false && $difftext !== false ) {
 411+ if ( $key !== false && $difftext !== false ) {
461412 wfIncrStats( 'diff_cache_miss' );
462413 $wgMemc->set( $key, $difftext, 7*86400 );
463414 } else {
@@ -588,9 +539,15 @@
589540 /**
590541 * Add the header to a diff body
591542 */
592 - static function addHeader( $diff, $otitle, $ntitle, $multi = '' ) {
 543+ function addHeader( $diff, $otitle, $ntitle, $multi = '' ) {
593544 global $wgOut;
594 -
 545+
 546+ if ( $this->mOldRev && $this->mOldRev->isDeleted(Revision::DELETED_TEXT) ) {
 547+ $otitle = '<span class="history-deleted">'.$otitle.'</span>';
 548+ }
 549+ if ( $this->mNewRev && $this->mNewRev->isDeleted(Revision::DELETED_TEXT) ) {
 550+ $ntitle = '<span class="history-deleted">'.$ntitle.'</span>';
 551+ }
595552 $header = "
596553 <table class='diff'>
597554 <col class='diff-marker' />
@@ -643,10 +600,10 @@
644601 : Revision::newFromTitle( $this->mTitle );
645602 if( !$this->mNewRev instanceof Revision )
646603 return false;
647 -
 604+
648605 // Update the new revision ID in case it was 0 (makes life easier doing UI stuff)
649606 $this->mNewid = $this->mNewRev->getId();
650 -
 607+
651608 // Set assorted variables
652609 $timestamp = $wgLang->timeanddate( $this->mNewRev->getTimestamp(), true );
653610 $this->mNewPage = $this->mNewRev->getTitle();
@@ -666,11 +623,6 @@
667624 $this->mNewtitle = "<a href='$newLink'>{$this->mPagetitle}</a>"
668625 . " (<a href='$newEdit'>" . htmlspecialchars( wfMsg( 'editold' ) ) . "</a>)";
669626 }
670 - if ( !$this->mNewRev->userCan(Revision::DELETED_TEXT) ) {
671 - $this->mNewtitle = "<span class='history-deleted'>{$this->mPagetitle}</span>";
672 - } else if ( $this->mNewRev->isDeleted(Revision::DELETED_TEXT) ) {
673 - $this->mNewtitle = '<span class="history-deleted">'.$this->mNewtitle.'</span>';
674 - }
675627
676628 // Load the old revision object
677629 $this->mOldRev = false;
@@ -698,20 +650,12 @@
699651 $t = $wgLang->timeanddate( $this->mOldRev->getTimestamp(), true );
700652 $oldLink = $this->mOldPage->escapeLocalUrl( 'oldid=' . $this->mOldid );
701653 $oldEdit = $this->mOldPage->escapeLocalUrl( 'action=edit&oldid=' . $this->mOldid );
702 - $this->mOldPagetitle = htmlspecialchars( wfMsg( 'revisionasof', $t ) );
 654+ $this->mOldtitle = "<a href='$oldLink'>" . htmlspecialchars( wfMsg( 'revisionasof', $t ) )
 655+ . "</a> (<a href='$oldEdit'>" . htmlspecialchars( wfMsg( 'editold' ) ) . "</a>)";
703656
704 - $this->mOldtitle = "<a href='$oldLink'>{$this->mOldPagetitle}</a>"
705 - . "(<a href='$oldEdit'>" . htmlspecialchars( wfMsg( 'editold' ) ) . "</a>)";
706657 // Add an "undo" link
707658 $newUndo = $this->mNewPage->escapeLocalUrl( 'action=edit&undoafter=' . $this->mOldid . '&undo=' . $this->mNewid);
708 - if ( $this->mNewRev->userCan(Revision::DELETED_TEXT) )
709 - $this->mNewtitle .= " (<a href='$newUndo'>" . htmlspecialchars( wfMsg( 'editundo' ) ) . "</a>)";
710 -
711 - if ( !$this->mOldRev->userCan(Revision::DELETED_TEXT) ) {
712 - $this->mOldtitle = "<span class='history-deleted'>{$this->mOldPagetitle}</span>";
713 - } else if ( $this->mOldRev->isDeleted(Revision::DELETED_TEXT) ) {
714 - $this->mOldtitle = '<span class="history-deleted">'.$this->mOldtitle.'</span>';
715 - }
 659+ $this->mNewtitle .= " (<a href='$newUndo'>" . htmlspecialchars( wfMsg( 'editundo' ) ) . "</a>)";
716660 }
717661
718662 return true;
@@ -732,6 +676,7 @@
733677 return false;
734678 }
735679 if ( $this->mOldRev ) {
 680+ // FIXME: permission tests
736681 $this->mOldtext = $this->mOldRev->revText();
737682 if ( $this->mOldtext === false ) {
738683 return false;
Index: trunk/phase3/maintenance/rebuildrecentchanges.inc
@@ -11,6 +11,7 @@
1212 {
1313 $fname = 'rebuildRecentChangesTablePass1';
1414 $dbw = wfGetDB( DB_MASTER );
 15+ extract( $dbw->tableNames( 'recentchanges', 'cur', 'old' ) );
1516
1617 $dbw->delete( 'recentchanges', '*' );
1718
@@ -34,7 +35,6 @@
3536 'rc_this_oldid' => 'rev_id',
3637 'rc_last_oldid' => 0, // is this ok?
3738 'rc_type' => $dbw->conditional( 'page_is_new != 0', RC_NEW, RC_EDIT ),
38 - 'rc_deleted' => 'rev_deleted'
3939 ), array(
4040 'rev_timestamp > ' . $dbw->addQuotes( $dbw->timestamp( $cutoff ) ),
4141 'rev_page=page_id'
@@ -99,70 +99,6 @@
100100
101101 function rebuildRecentChangesTablePass3()
102102 {
103 - $fname = 'rebuildRecentChangesTablePass3';
104 - $dbw = wfGetDB( DB_MASTER );
105 -
106 - print( "Loading from user, page, and logging tables...\n" );
107 -
108 - global $wgRCMaxAge, $wgLogRestrictions;
109 -
110 - // Exclude non-public logs
111 - $avoidLogs = array();
112 - if( isset($wgLogRestrictions) ) {
113 - foreach ( $wgLogRestrictions as $logtype => $right ) {
114 - // Do not show private logs when not specifically requested
115 - if ( $right !='*' ) {
116 - $safetype =$dbw->strencode( $logtype );
117 - $avoidLogs[] = "'$safetype'";
118 - }
119 - }
120 - }
121 - // Some logs don't go in RC. This can't really detect all of those ... :(
122 - $avoidLogs[] = "'patrol'"; // hack...we don't want this here
123 -
124 - if( !empty($avoidLogs) ) {
125 - $skipLogs = 'log_type NOT IN(' . implode(',',$avoidLogs) . ')';
126 - } else {
127 - $skipLogs = '1 = 1';
128 - }
129 -
130 - $cutoff = time() - $wgRCMaxAge;
131 - $dbw->insertSelect( 'recentchanges', array( 'logging', 'page', 'user' ),
132 - array(
133 - 'rc_timestamp' => 'log_timestamp',
134 - 'rc_cur_time' => 'log_timestamp',
135 - 'rc_user' => 'log_user',
136 - 'rc_user_text' => 'user_name',
137 - 'rc_namespace' => 'log_namespace',
138 - 'rc_title' => 'log_title',
139 - 'rc_comment' => 'log_comment',
140 - 'rc_minor' => 0,
141 - 'rc_bot' => 0,
142 - 'rc_new' => 0,
143 - 'rc_cur_id' => 0,
144 - 'rc_this_oldid' => 0,
145 - 'rc_last_oldid' => 0,
146 - 'rc_type' => RC_LOG,
147 - 'rc_cur_id' => 'page_id',
148 - 'rc_log_type' => 'log_type',
149 - 'rc_log_action' => 'log_action',
150 - 'rc_logid' => 'log_id',
151 - 'rc_params' => 'log_params',
152 - 'rc_deleted' => 'log_deleted'
153 - ), array(
154 - 'log_timestamp > ' . $dbw->addQuotes( $dbw->timestamp( $cutoff ) ),
155 - 'log_user=user_id',
156 - 'log_namespace=page_namespace',
157 - 'log_title=page_title',
158 - $skipLogs
159 - ), $fname,
160 - array(), // INSERT options
161 - array( 'ORDER BY' => 'log_timestamp DESC', 'LIMIT' => 5000 ) // SELECT options
162 - );
163 -}
164 -
165 -function rebuildRecentChangesTablePass4()
166 -{
167103 global $wgGroupPermissions, $wgUseRCPatrol;
168104
169105 $dbw = wfGetDB( DB_MASTER );
Index: trunk/phase3/maintenance/rebuildrecentchanges.php
@@ -17,8 +17,7 @@
1818
1919 rebuildRecentChangesTablePass1();
2020 rebuildRecentChangesTablePass2();
21 -rebuildRecentChangesTablePass3(); // logs entries
22 -rebuildRecentChangesTablePass4(); // flag bot edits
 21+rebuildRecentChangesTablePass3(); // flag bot edits
2322
2423 print "Done.\n";
2524 exit();

Follow-up revisions

RevisionCommit summaryAuthorDate
r26331Merged revisions 26280-26330 via svnmerge from...david22:28, 2 October 2007

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r26281*Clean up deletion of revisions and remove some gaps...aaron19:38, 1 October 2007

Status & tagging log