Index: trunk/phase3/languages/messages/MessagesEn.php |
— | — | @@ -782,8 +782,6 @@ |
783 | 783 | 'formerror' => 'Error: could not submit form', |
784 | 784 | 'badarticleerror' => 'This action cannot be performed on this page.', |
785 | 785 | '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.', |
788 | 786 | 'badtitle' => 'Bad title', |
789 | 787 | '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.', |
790 | 788 | '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 @@ |
1149 | 1147 | </div>', |
1150 | 1148 | 'rev-delundel' => 'show/hide', |
1151 | 1149 | '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:'''", |
1157 | 1154 | 'revdelete-text' => 'Deleted revisions and events will still appear in the page history and logs, |
1158 | 1155 | but parts of their content will be inaccessible to the public. |
1159 | 1156 | |
— | — | @@ -1163,7 +1160,7 @@ |
1164 | 1161 | 'revdelete-hide-name' => 'Hide action and target', |
1165 | 1162 | 'revdelete-hide-comment' => 'Hide edit comment', |
1166 | 1163 | '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', |
1168 | 1165 | 'revdelete-suppress' => 'Suppress data from sysops as well as others', |
1169 | 1166 | 'revdelete-hide-image' => 'Hide file content', |
1170 | 1167 | 'revdelete-unsuppress' => 'Remove restrictions on restored revisions', |
— | — | @@ -1172,44 +1169,15 @@ |
1173 | 1170 | 'revdelete-logentry' => 'changed revision visibility of [[$1]]', |
1174 | 1171 | 'logdelete-logentry' => 'changed event visibility of [[$1]]', |
1175 | 1172 | '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.', |
1180 | 1176 | |
1181 | 1177 | # 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.', |
1186 | 1181 | |
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 | | - |
1214 | 1182 | # Diffs |
1215 | 1183 | 'history-title' => 'Revision history of "$1"', |
1216 | 1184 | 'difference' => '(Difference between revisions)', |
— | — | @@ -1354,11 +1322,6 @@ |
1355 | 1323 | 'grouppage-sysop' => '{{ns:project}}:Administrators', |
1356 | 1324 | 'grouppage-bureaucrat' => '{{ns:project}}:Bureaucrats', |
1357 | 1325 | |
1358 | | -'oversight' => 'Oversight', |
1359 | | -'group-oversight' => 'Oversights', |
1360 | | -'group-oversight-member' => 'Oversight', |
1361 | | -'grouppage-oversight' => '{{ns:project}}:Oversight', |
1362 | | - |
1363 | 1326 | # User rights log |
1364 | 1327 | 'rightslog' => 'User rights log', |
1365 | 1328 | 'rightslogtext' => 'This is a log of changes to user rights.', |
— | — | @@ -1702,7 +1665,6 @@ |
1703 | 1666 | 'specialpages-summary' => '', # only translate this message to other languages if you have to change it |
1704 | 1667 | 'spheading' => 'Special pages for all users', |
1705 | 1668 | 'restrictedpheading' => 'Restricted special pages', |
1706 | | -'restrictedlheading' => 'Restricted logs', |
1707 | 1669 | 'rclsub' => '(to pages linked from "$1")', |
1708 | 1670 | 'newpages' => 'New pages', |
1709 | 1671 | 'newpages-summary' => '', # only translate this message to other languages if you have to change it |
— | — | @@ -1741,10 +1703,10 @@ |
1742 | 1704 | 'specialloguserlabel' => 'User:', |
1743 | 1705 | 'speciallogtitlelabel' => 'Title:', |
1744 | 1706 | 'log' => 'Logs', |
1745 | | -'all-logs-page' => 'All public logs', |
| 1707 | +'all-logs-page' => 'All logs', |
1746 | 1708 | 'log-search-legend' => 'Search for logs', |
1747 | 1709 | '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}}. |
1749 | 1711 | You can narrow down the view by selecting a log type, the user name, or the affected page.', |
1750 | 1712 | 'logempty' => 'No matching items in log.', |
1751 | 1713 | 'log-title-wildcard' => 'Search titles starting with this text', |
— | — | @@ -1891,7 +1853,6 @@ |
1892 | 1854 | 'deletedtext' => '"$1" has been deleted. |
1893 | 1855 | See $2 for a record of recent deletions.', |
1894 | 1856 | 'deletedarticle' => 'deleted "[[$1]]"', |
1895 | | -'suppressedarticle' => 'suppressed "[[$1]]"', |
1896 | 1857 | 'dellogpage' => 'Deletion log', |
1897 | 1858 | 'dellogpagetext' => 'Below is a list of the most recent deletions.', |
1898 | 1859 | 'deletionlog' => 'deletion log', |
— | — | @@ -1912,7 +1873,6 @@ |
1913 | 1874 | 'sessionfailure' => 'There seems to be a problem with your login session; |
1914 | 1875 | this action has been canceled as a precaution against session hijacking. |
1915 | 1876 | Please hit "back" and reload the page you came from, then try again.', |
1916 | | - |
1917 | 1877 | 'protectlogpage' => 'Protection log', |
1918 | 1878 | '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.', |
1919 | 1879 | 'protectedarticle' => 'protected "[[$1]]"', |
— | — | @@ -1920,7 +1880,6 @@ |
1921 | 1881 | 'unprotectedarticle' => 'unprotected "[[$1]]"', |
1922 | 1882 | 'protectsub' => '(Setting protection level for "$1")', |
1923 | 1883 | 'confirmprotect' => 'Confirm protection', |
1924 | | -'protect-fileonly' => 'Apply edit restrictions to file uploads only', |
1925 | 1884 | 'protectcomment' => 'Comment:', |
1926 | 1885 | 'protectexpiry' => 'Expires:', |
1927 | 1886 | 'protect_expiry_invalid' => 'Expiry time is invalid.', |
— | — | @@ -1951,7 +1910,6 @@ |
1952 | 1911 | # Restrictions (nouns) |
1953 | 1912 | 'restriction-edit' => 'Edit', |
1954 | 1913 | 'restriction-move' => 'Move', |
1955 | | -'restriction-upload' => 'Upload', |
1956 | 1914 | |
1957 | 1915 | # Restriction levels |
1958 | 1916 | 'restriction-level-sysop' => 'full protected', |
— | — | @@ -1960,29 +1918,25 @@ |
1961 | 1919 | |
1962 | 1920 | # Undelete |
1963 | 1921 | 'undelete' => 'View deleted pages', |
1964 | | -'undeleterevs' => 'Deleted revisions', |
1965 | 1922 | 'undeletepage' => 'View and restore deleted pages', |
1966 | 1923 | 'viewdeletedpage' => 'View deleted pages', |
1967 | | -'undeletepagetitle' => '\'\'\'The following consists of deleted revisions of [[:$1]]\'\'\'.', |
1968 | 1924 | 'undeletepagetext' => 'The following pages have been deleted but are still in the archive and |
1969 | 1925 | 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.", |
1974 | 1930 | 'undeleterevisions' => '$1 {{PLURAL:$1|revision|revisions}} archived', |
1975 | 1931 | 'undeletehistory' => 'If you restore the page, all revisions will be restored to the history. |
1976 | 1932 | If a new page with the same name has been created since the deletion, the restored |
1977 | 1933 | 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.", |
1981 | 1938 | 'undeletehistorynoadmin' => 'This article has been deleted. The reason for deletion is |
1982 | 1939 | shown in the summary below, along with details of the users who had edited this page |
1983 | 1940 | 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 | | - |
1987 | 1941 | 'undelete-revision' => 'Deleted revision of $1 (as of $2) by $3:', |
1988 | 1942 | 'undeleterevision-missing' => 'Invalid or missing revision. You may have a bad link, or the |
1989 | 1943 | 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> </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×tamp=$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 @@ |
26 | 26 | * rc_patrolled boolean whether or not someone has marked this edit as patrolled |
27 | 27 | * rc_old_len integer byte length of the text before the edit |
28 | 28 | * 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 |
34 | 29 | * |
35 | 30 | * mExtra: |
36 | 31 | * prefixedDBkey prefixed db key, used by external app via msg queue |
— | — | @@ -300,12 +295,7 @@ |
301 | 296 | 'rc_patrolled' => 0, |
302 | 297 | 'rc_new' => 0, # obsolete |
303 | 298 | '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 |
310 | 300 | ); |
311 | 301 | |
312 | 302 | $rc->mExtra = array( |
— | — | @@ -326,9 +316,11 @@ |
327 | 317 | public static function notifyNew( $timestamp, &$title, $minor, &$user, $comment, $bot = 'default', |
328 | 318 | $ip='', $size = 0, $newId = 0 ) |
329 | 319 | { |
330 | | - if( !$ip ) { |
| 320 | + if ( !$ip ) { |
331 | 321 | $ip = wfGetIP(); |
332 | | - if( !$ip ) $ip = ''; |
| 322 | + if ( !$ip ) { |
| 323 | + $ip = ''; |
| 324 | + } |
333 | 325 | } |
334 | 326 | if ( $bot === 'default' ) { |
335 | 327 | $bot = $user->isAllowed( 'bot' ); |
— | — | @@ -353,14 +345,9 @@ |
354 | 346 | 'rc_moved_to_title' => '', |
355 | 347 | 'rc_ip' => $ip, |
356 | 348 | 'rc_patrolled' => 0, |
357 | | - 'rc_new' => 1, # obsolete |
| 349 | + 'rc_new' => 1, # obsolete |
358 | 350 | '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 |
365 | 352 | ); |
366 | 353 | |
367 | 354 | $rc->mExtra = array( |
— | — | @@ -376,9 +363,11 @@ |
377 | 364 | # Makes an entry in the database corresponding to a rename |
378 | 365 | public static function notifyMove( $timestamp, &$oldTitle, &$newTitle, &$user, $comment, $ip='', $overRedir = false ) |
379 | 366 | { |
380 | | - if( !$ip ) { |
| 367 | + if ( !$ip ) { |
381 | 368 | $ip = wfGetIP(); |
382 | | - if( !$ip ) $ip = ''; |
| 369 | + if ( !$ip ) { |
| 370 | + $ip = ''; |
| 371 | + } |
383 | 372 | } |
384 | 373 | |
385 | 374 | $rc = new RecentChange; |
— | — | @@ -403,11 +392,6 @@ |
404 | 393 | 'rc_patrolled' => 1, |
405 | 394 | 'rc_old_len' => NULL, |
406 | 395 | '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' => '' |
412 | 396 | ); |
413 | 397 | |
414 | 398 | $rc->mExtra = array( |
— | — | @@ -426,27 +410,30 @@ |
427 | 411 | RecentChange::notifyMove( $timestamp, $oldTitle, $newTitle, $user, $comment, $ip, true ); |
428 | 412 | } |
429 | 413 | |
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 |
431 | 416 | public static function notifyLog( $timestamp, &$title, &$user, $comment, $ip='', |
432 | | - $type, $action, $target, $logComment, $params, $newId=0 ) |
| 417 | + $type, $action, $target, $logComment, $params ) |
433 | 418 | { |
434 | | - if( !$ip ) { |
| 419 | + if ( !$ip ) { |
435 | 420 | $ip = wfGetIP(); |
436 | | - if( !$ip ) $ip = ''; |
| 421 | + if ( !$ip ) { |
| 422 | + $ip = ''; |
| 423 | + } |
437 | 424 | } |
438 | 425 | |
439 | 426 | $rc = new RecentChange; |
440 | 427 | $rc->mAttribs = array( |
441 | 428 | 'rc_timestamp' => $timestamp, |
442 | 429 | 'rc_cur_time' => $timestamp, |
443 | | - 'rc_namespace' => $target->getNamespace(), |
444 | | - 'rc_title' => $target->getDBkey(), |
| 430 | + 'rc_namespace' => $title->getNamespace(), |
| 431 | + 'rc_title' => $title->getDBkey(), |
445 | 432 | 'rc_type' => RC_LOG, |
446 | 433 | 'rc_minor' => 0, |
447 | | - 'rc_cur_id' => $target->getArticleID(), |
| 434 | + 'rc_cur_id' => $title->getArticleID(), |
448 | 435 | 'rc_user' => $user->getID(), |
449 | 436 | 'rc_user_text' => $user->getName(), |
450 | | - 'rc_comment' => $logComment, |
| 437 | + 'rc_comment' => $comment, |
451 | 438 | 'rc_this_oldid' => 0, |
452 | 439 | 'rc_last_oldid' => 0, |
453 | 440 | 'rc_bot' => $user->isAllowed( 'bot' ) ? 1 : 0, |
— | — | @@ -457,11 +444,6 @@ |
458 | 445 | 'rc_new' => 0, # obsolete |
459 | 446 | 'rc_old_len' => NULL, |
460 | 447 | '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 |
466 | 448 | ); |
467 | 449 | $rc->mExtra = array( |
468 | 450 | 'prefixedDBkey' => $title->getPrefixedDBkey(), |
— | — | @@ -508,11 +490,6 @@ |
509 | 491 | 'rc_new' => $row->page_is_new, # obsolete |
510 | 492 | 'rc_old_len' => $row->rc_old_len, |
511 | 493 | '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 |
517 | 494 | ); |
518 | 495 | |
519 | 496 | $this->mExtra = array(); |
Index: trunk/phase3/includes/PageHistory.php |
— | — | @@ -37,21 +37,7 @@ |
38 | 38 | $this->mTitle =& $article->mTitle; |
39 | 39 | $this->mNotificationTimestamp = NULL; |
40 | 40 | $this->mSkin = $wgUser->getSkin(); |
41 | | - $this->preCacheMessages(); |
42 | 41 | } |
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 | | - } |
56 | 42 | |
57 | 43 | /** |
58 | 44 | * Print the history page for an article. |
— | — | @@ -203,31 +189,35 @@ |
204 | 190 | $arbitrary = $this->diffButtons( $rev, $firstInList, $counter ); |
205 | 191 | $link = $this->revLink( $rev ); |
206 | 192 | |
| 193 | + $user = $this->mSkin->userLink( $rev->getUser(), $rev->getUserText() ) |
| 194 | + . $this->mSkin->userToolLinks( $rev->getUser(), $rev->getUserText() ); |
| 195 | + |
207 | 196 | $s .= "($curlink) ($lastlink) $arbitrary"; |
208 | 197 | |
209 | 198 | if( $wgUser->isAllowed( 'deleterevision' ) ) { |
210 | 199 | $revdel = SpecialPage::getTitleFor( 'Revisiondelete' ); |
211 | 200 | 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' ); |
214 | 203 | } else if( !$rev->userCan( Revision::DELETED_RESTRICTED ) ) { |
215 | 204 | // If revision was hidden from sysops |
216 | | - $del = $this->message['rev-delundel']; |
| 205 | + $del = wfMsgHtml( 'rev-delundel' ); |
217 | 206 | } else { |
218 | 207 | $del = $this->mSkin->makeKnownLinkObj( $revdel, |
219 | | - $this->message['rev-delundel'], |
| 208 | + wfMsg( 'rev-delundel' ), |
220 | 209 | 'target=' . urlencode( $this->mTitle->getPrefixedDbkey() ) . |
221 | 210 | '&oldid=' . urlencode( $rev->getId() ) ); |
222 | | - // Bolden oversighted content |
223 | | - if( $rev->isDeleted( Revision::DELETED_RESTRICTED ) ) |
224 | | - $del = "<strong>$del</strong>"; |
225 | 211 | } |
226 | | - $s .= " <tt>(<small>$del</small>)</tt> "; |
| 212 | + $s .= " (<small>$del</small>) "; |
227 | 213 | } |
228 | 214 | |
229 | 215 | $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 | + |
232 | 222 | if( $row->rev_minor_edit ) { |
233 | 223 | $s .= ' ' . wfElement( 'span', array( 'class' => 'minor' ), wfMsg( 'minoreditletter') ); |
234 | 224 | } |
— | — | @@ -253,7 +243,7 @@ |
254 | 244 | } |
255 | 245 | #add blurb about text having been deleted |
256 | 246 | if( $row->rev_deleted & Revision::DELETED_TEXT ) { |
257 | | - $s .= ' <tt>' . wfMsgHtml( 'deletedrev' ) . '</tt>'; |
| 247 | + $s .= ' ' . wfMsgHtml( 'deletedrev' ); |
258 | 248 | } |
259 | 249 | |
260 | 250 | $tools = array(); |
— | — | @@ -302,7 +292,7 @@ |
303 | 293 | |
304 | 294 | /** @todo document */ |
305 | 295 | function curLink( $rev, $latest ) { |
306 | | - $cur = $this->message['cur']; |
| 296 | + $cur = wfMsgExt( 'cur', array( 'escape') ); |
307 | 297 | if( $latest || !$rev->userCan( Revision::DELETED_TEXT ) ) { |
308 | 298 | return $cur; |
309 | 299 | } else { |
— | — | @@ -315,7 +305,7 @@ |
316 | 306 | |
317 | 307 | /** @todo document */ |
318 | 308 | function lastLink( $rev, $next, $counter ) { |
319 | | - $last = $this->message['last']; |
| 309 | + $last = wfMsgExt( 'last', array( 'escape' ) ); |
320 | 310 | if ( is_null( $next ) ) { |
321 | 311 | # Probably no next row |
322 | 312 | return $last; |
Index: trunk/phase3/includes/SpecialRecentchanges.php |
— | — | @@ -408,7 +408,7 @@ |
409 | 409 | rcFormatDiff( $obj ), |
410 | 410 | $title->getFullURL(), |
411 | 411 | $obj->rc_timestamp, |
412 | | - ($obj->rc_deleted & Revision::DELETED_USER) ? wfMsgHtml('rev-deleted-user') : $obj->rc_user_text, |
| 412 | + $obj->rc_user_text, |
413 | 413 | $talkpage->getFullURL() |
414 | 414 | ); |
415 | 415 | $feed->outItem( $item ); |
— | — | @@ -617,18 +617,15 @@ |
618 | 618 | return rcFormatDiffRow( $titleObj, |
619 | 619 | $row->rc_last_oldid, $row->rc_this_oldid, |
620 | 620 | $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 ); |
623 | 622 | } |
624 | 623 | |
625 | | -function rcFormatDiffRow( $title, $oldid, $newid, $timestamp, $comment, $actiontext='' ) { |
| 624 | +function rcFormatDiffRow( $title, $oldid, $newid, $timestamp, $comment ) { |
626 | 625 | global $wgFeedDiffCutoff, $wgContLang, $wgUser; |
627 | 626 | $fname = 'rcFormatDiff'; |
628 | 627 | wfProfileIn( $fname ); |
629 | 628 | |
630 | 629 | $skin = $wgUser->getSkin(); |
631 | | - # log enties |
632 | | - if( $actiontext ) $comment = "$actiontext $comment"; |
633 | 630 | $completeText = '<p>' . $skin->formatComment( $comment ) . "</p>\n"; |
634 | 631 | |
635 | 632 | //NOTE: Check permissions for anonymous users, not current user. |
Index: trunk/phase3/includes/SpecialPage.php |
— | — | @@ -131,7 +131,7 @@ |
132 | 132 | 'Log' => array( 'SpecialPage', 'Log' ), |
133 | 133 | 'Blockip' => array( 'SpecialPage', 'Blockip', 'block' ), |
134 | 134 | 'Undelete' => array( 'SpecialPage', 'Undelete', 'deletedhistory' ), |
135 | | - 'Import' => array( 'SpecialPage', 'Import', 'import' ), |
| 135 | + 'Import' => array( 'SpecialPage', "Import", 'import' ), |
136 | 136 | 'Lockdb' => array( 'SpecialPage', 'Lockdb', 'siteadmin' ), |
137 | 137 | 'Unlockdb' => array( 'SpecialPage', 'Unlockdb', 'siteadmin' ), |
138 | 138 | 'Userrights' => array( 'SpecialPage', 'Userrights', 'userrights' ), |
— | — | @@ -147,7 +147,6 @@ |
148 | 148 | 'Mytalk' => array( 'SpecialMytalk' ), |
149 | 149 | 'Mycontributions' => array( 'SpecialMycontributions' ), |
150 | 150 | 'Listadmins' => array( 'SpecialRedirectToSpecial', 'Listadmins', 'Listusers', 'sysop' ), |
151 | | - 'MergeHistory' => array( 'SpecialPage', 'Mergehistory', 'mergehistory' ), |
152 | 151 | ); |
153 | 152 | |
154 | 153 | static public $mAliases; |
— | — | @@ -380,28 +379,6 @@ |
381 | 380 | } |
382 | 381 | return $pages; |
383 | 382 | } |
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 | | - } |
406 | 383 | |
407 | 384 | /** |
408 | 385 | * Execute a special page path. |
Index: trunk/phase3/includes/Title.php |
— | — | @@ -2445,38 +2445,6 @@ |
2446 | 2446 | } |
2447 | 2447 | |
2448 | 2448 | /** |
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 | | - /** |
2481 | 2449 | * Can this title be added to a user's watchlist? |
2482 | 2450 | * |
2483 | 2451 | * @return bool |
Index: trunk/phase3/includes/SpecialContributions.php |
— | — | @@ -171,7 +171,7 @@ |
172 | 172 | } |
173 | 173 | $histlink='('.$sk->makeKnownLinkObj( $page, $this->messages['hist'], 'action=history' ) . ')'; |
174 | 174 | |
175 | | - $comment = $wgContLang->getDirMark() . $sk->revComment( $rev, false, true ); |
| 175 | + $comment = $wgContLang->getDirMark() . $sk->revComment( $rev ); |
176 | 176 | $d = $wgLang->timeanddate( wfTimestamp( TS_MW, $row->rev_timestamp ), true ); |
177 | 177 | |
178 | 178 | if( $this->target == 'newbies' ) { |
Index: trunk/phase3/includes/filerepo/LocalFile.php |
— | — | @@ -46,8 +46,7 @@ |
47 | 47 | $sha1, # SHA-1 base 36 content hash |
48 | 48 | $dataLoaded, # Whether or not all this has been loaded from the database (loadFromXxx) |
49 | 49 | $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 |
52 | 51 | |
53 | 52 | /**#@-*/ |
54 | 53 | |
— | — | @@ -237,13 +236,8 @@ |
238 | 237 | $this->$name = $value; |
239 | 238 | } |
240 | 239 | $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(); |
248 | 242 | } |
249 | 243 | |
250 | 244 | /** |
— | — | @@ -578,9 +572,7 @@ |
579 | 573 | $this->historyRes = $dbr->select( 'image', |
580 | 574 | array( |
581 | 575 | '*', |
582 | | - "'' AS oi_archive_name", |
583 | | - '0 as oi_deleted', |
584 | | - 'img_sha1' |
| 576 | + "'' AS oi_archive_name" |
585 | 577 | ), |
586 | 578 | array( 'img_name' => $this->title->getDBkey() ), |
587 | 579 | __METHOD__ |
— | — | @@ -749,7 +741,7 @@ |
750 | 742 | 'oi_media_type' => 'img_media_type', |
751 | 743 | 'oi_major_mime' => 'img_major_mime', |
752 | 744 | 'oi_minor_mime' => 'img_minor_mime', |
753 | | - 'oi_sha1' => 'img_sha1' |
| 745 | + 'oi_sha1' => 'img_sha1', |
754 | 746 | ), array( 'img_name' => $this->getName() ), __METHOD__ |
755 | 747 | ); |
756 | 748 | |
— | — | @@ -865,9 +857,9 @@ |
866 | 858 | * @param $reason |
867 | 859 | * @return FileRepoStatus object. |
868 | 860 | */ |
869 | | - function delete( $reason, $suppress=false ) { |
| 861 | + function delete( $reason ) { |
870 | 862 | $this->lock(); |
871 | | - $batch = new LocalFileDeleteBatch( $this, $reason, $suppress ); |
| 863 | + $batch = new LocalFileDeleteBatch( $this, $reason ); |
872 | 864 | $batch->addCurrent(); |
873 | 865 | |
874 | 866 | # Get old version relative paths |
— | — | @@ -903,9 +895,9 @@ |
904 | 896 | * @throws MWException or FSException on database or filestore failure |
905 | 897 | * @return FileRepoStatus object. |
906 | 898 | */ |
907 | | - function deleteOld( $archiveName, $reason, $suppress=false ) { |
| 899 | + function deleteOld( $archiveName, $reason ) { |
908 | 900 | $this->lock(); |
909 | | - $batch = new LocalFileDeleteBatch( $this, $reason, $suppress ); |
| 901 | + $batch = new LocalFileDeleteBatch( $this, $reason ); |
910 | 902 | $batch->addOld( $archiveName ); |
911 | 903 | $status = $batch->execute(); |
912 | 904 | $this->unlock(); |
— | — | @@ -916,21 +908,22 @@ |
917 | 909 | return $status; |
918 | 910 | } |
919 | 911 | |
920 | | - /* |
| 912 | + /** |
921 | 913 | * Restore all or specified deleted revisions to the given file. |
922 | 914 | * Permissions and logging are left to the caller. |
923 | 915 | * |
924 | 916 | * May throw database exceptions on error. |
925 | 917 | * |
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. |
927 | 920 | * @return FileRepoStatus |
928 | 921 | */ |
929 | | - function restore( $timestamp = 0, $unsuppress = false ) { |
| 922 | + function restore( $versions = array(), $unsuppress = false ) { |
930 | 923 | $batch = new LocalFileRestoreBatch( $this ); |
931 | | - if ( !$timestamp ) { |
| 924 | + if ( !$versions ) { |
932 | 925 | $batch->addAll(); |
933 | 926 | } else { |
934 | | - $batch->addAll( $timestamp ); |
| 927 | + $batch->addIds( $versions ); |
935 | 928 | } |
936 | 929 | $status = $batch->execute(); |
937 | 930 | if ( !$status->ok ) { |
— | — | @@ -1110,10 +1103,9 @@ |
1111 | 1104 | var $file, $reason, $srcRels = array(), $archiveUrls = array(), $deletionBatch; |
1112 | 1105 | var $status; |
1113 | 1106 | |
1114 | | - function __construct( File $file, $reason = '', $suppress=false ) { |
| 1107 | + function __construct( File $file, $reason = '' ) { |
1115 | 1108 | $this->file = $file; |
1116 | 1109 | $this->reason = $reason; |
1117 | | - $this->suppress = $suppress; |
1118 | 1110 | $this->status = $file->repo->newGood(); |
1119 | 1111 | } |
1120 | 1112 | |
— | — | @@ -1194,16 +1186,6 @@ |
1195 | 1187 | $dotExt = $ext === '' ? '' : ".$ext"; |
1196 | 1188 | $encExt = $dbw->addQuotes( $dotExt ); |
1197 | 1189 | 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 | | - } |
1208 | 1190 | |
1209 | 1191 | if ( $deleteCurrent ) { |
1210 | 1192 | $concat = $dbw->buildConcat( array( "img_sha1", $encExt ) ); |
— | — | @@ -1215,7 +1197,7 @@ |
1216 | 1198 | 'fa_deleted_user' => $encUserId, |
1217 | 1199 | 'fa_deleted_timestamp' => $encTimestamp, |
1218 | 1200 | 'fa_deleted_reason' => $encReason, |
1219 | | - 'fa_deleted' => $this->suppress ? $bitfield : 0, |
| 1201 | + 'fa_deleted' => 0, |
1220 | 1202 | |
1221 | 1203 | 'fa_name' => 'img_name', |
1222 | 1204 | 'fa_archive_name' => 'NULL', |
— | — | @@ -1246,7 +1228,7 @@ |
1247 | 1229 | 'fa_deleted_user' => $encUserId, |
1248 | 1230 | 'fa_deleted_timestamp' => $encTimestamp, |
1249 | 1231 | 'fa_deleted_reason' => $encReason, |
1250 | | - 'fa_deleted' => $this->suppress ? $bitfield : 'oi_deleted', |
| 1232 | + 'fa_deleted' => 0, |
1251 | 1233 | |
1252 | 1234 | 'fa_name' => 'oi_name', |
1253 | 1235 | 'fa_archive_name' => 'oi_archive_name', |
— | — | @@ -1289,25 +1271,7 @@ |
1290 | 1272 | wfProfileIn( __METHOD__ ); |
1291 | 1273 | |
1292 | 1274 | $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 | + |
1312 | 1276 | // Prepare deletion batch |
1313 | 1277 | $hashes = $this->getHashes(); |
1314 | 1278 | $this->deletionBatch = array(); |
— | — | @@ -1315,8 +1279,7 @@ |
1316 | 1280 | $dotExt = $ext === '' ? '' : ".$ext"; |
1317 | 1281 | foreach ( $this->srcRels as $name => $srcRel ) { |
1318 | 1282 | // 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] ) ) { |
1321 | 1284 | $hash = $hashes[$name]; |
1322 | 1285 | $key = $hash . $dotExt; |
1323 | 1286 | $dstRel = $this->file->repo->getDeletedHashPath( $key ) . $key; |
— | — | @@ -1345,19 +1308,6 @@ |
1346 | 1309 | $this->file->unlockAndRollback(); |
1347 | 1310 | return $this->status; |
1348 | 1311 | } |
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 | | - } |
1362 | 1312 | |
1363 | 1313 | // Purge squid |
1364 | 1314 | if ( $wgUseSquid ) { |
— | — | @@ -1369,6 +1319,9 @@ |
1370 | 1320 | SquidUpdate::purge( $urls ); |
1371 | 1321 | } |
1372 | 1322 | |
| 1323 | + // Delete image/oldimage rows |
| 1324 | + $this->doDBDeletes(); |
| 1325 | + |
1373 | 1326 | // Commit and return |
1374 | 1327 | $this->file->unlock(); |
1375 | 1328 | wfProfileOut( __METHOD__ ); |
— | — | @@ -1382,13 +1335,12 @@ |
1383 | 1336 | * Helper class for file undeletion |
1384 | 1337 | */ |
1385 | 1338 | class LocalFileRestoreBatch { |
1386 | | - var $file, $cleanupBatch, $ids, $all; |
| 1339 | + var $file, $cleanupBatch, $ids, $all, $unsuppress = false; |
1387 | 1340 | |
1388 | | - function __construct( File $file, $unsuppress = false ) { |
| 1341 | + function __construct( File $file ) { |
1389 | 1342 | $this->file = $file; |
1390 | 1343 | $this->cleanupBatch = $this->ids = array(); |
1391 | 1344 | $this->ids = array(); |
1392 | | - $this->unsuppress = $unsuppress; |
1393 | 1345 | } |
1394 | 1346 | |
1395 | 1347 | /** |
— | — | @@ -1407,11 +1359,9 @@ |
1408 | 1360 | |
1409 | 1361 | /** |
1410 | 1362 | * Add all revisions of the file |
1411 | | - * Can be all from $timestamp if given |
1412 | 1363 | */ |
1413 | | - function addAll( $timestamp = false ) { |
| 1364 | + function addAll() { |
1414 | 1365 | $this->all = true; |
1415 | | - $this->timestamp = $timestamp; |
1416 | 1366 | } |
1417 | 1367 | |
1418 | 1368 | /** |
— | — | @@ -1432,16 +1382,11 @@ |
1433 | 1383 | $dbw = $this->file->repo->getMasterDB(); |
1434 | 1384 | $status = $this->file->repo->newGood(); |
1435 | 1385 | |
1436 | | - $revisionDeleter = new RevisionDeleter( $dbw ); |
1437 | | - $privateFiles = array(); |
1438 | | - |
1439 | 1386 | // Fetch all or selected archived revisions for the file, |
1440 | 1387 | // sorted from the most recent to the oldest. |
1441 | 1388 | $conditions = array( 'fa_name' => $this->file->getName() ); |
1442 | 1389 | if( !$this->all ) { |
1443 | 1390 | $conditions[] = 'fa_id IN (' . $dbw->makeList( $this->ids ) . ')'; |
1444 | | - } else if( $this->timestamp ) { |
1445 | | - $conditions[] = "fa_timestamp >= {$this->timestamp}"; |
1446 | 1391 | } |
1447 | 1392 | |
1448 | 1393 | $result = $dbw->select( 'filearchive', '*', |
— | — | @@ -1458,7 +1403,12 @@ |
1459 | 1404 | $archiveNames = array(); |
1460 | 1405 | while( $row = $dbw->fetchObject( $result ) ) { |
1461 | 1406 | $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 | + } |
1463 | 1413 | if ( $row->fa_name != $this->file->getName() ) { |
1464 | 1414 | $status->error( 'undelete-filename-mismatch', $wgLang->timeanddate( $row->fa_timestamp ) ); |
1465 | 1415 | $status->failCount++; |
— | — | @@ -1496,11 +1446,6 @@ |
1497 | 1447 | } |
1498 | 1448 | |
1499 | 1449 | if ( $first && !$exists ) { |
1500 | | - // The live (current) version cannot be hidden! |
1501 | | - if( $row->fa_deleted ) { |
1502 | | - $this->file->unlock(); |
1503 | | - return $status; |
1504 | | - } |
1505 | 1450 | // This revision will be published as the new current version |
1506 | 1451 | $destRel = $this->file->getRel(); |
1507 | 1452 | $insertCurrent = array( |
— | — | @@ -1547,21 +1492,13 @@ |
1548 | 1493 | 'oi_media_type' => $props['media_type'], |
1549 | 1494 | 'oi_major_mime' => $props['major_mime'], |
1550 | 1495 | 'oi_minor_mime' => $props['minor_mime'], |
1551 | | - 'oi_deleted' => $this->unsuppress ? 0 : $row->fa_deleted, |
| 1496 | + 'oi_deleted' => $row->fa_deleted, |
1552 | 1497 | 'oi_sha1' => $sha1 ); |
1553 | 1498 | } |
1554 | 1499 | |
1555 | 1500 | $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; |
1566 | 1503 | $first = false; |
1567 | 1504 | } |
1568 | 1505 | unset( $result ); |
— | — | @@ -1601,16 +1538,6 @@ |
1602 | 1539 | array( 'fa_id IN (' . $dbw->makeList( $deleteIds ) . ')' ), |
1603 | 1540 | __METHOD__ ); |
1604 | 1541 | } |
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 | | - } |
1615 | 1542 | |
1616 | 1543 | if( $status->successCount > 0 ) { |
1617 | 1544 | if( !$exists ) { |
Index: trunk/phase3/includes/filerepo/FSRepo.php |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | */ |
8 | 8 | |
9 | 9 | class FSRepo extends FileRepo { |
10 | | - var $directory, $deletedDir, $hiddenDir, $url, $hashLevels, $deletedHashLevels; |
| 10 | + var $directory, $deletedDir, $url, $hashLevels, $deletedHashLevels; |
11 | 11 | var $fileFactory = array( 'UnregisteredLocalFile', 'newFromTitle' ); |
12 | 12 | var $oldFileFactory = false; |
13 | 13 | var $pathDisclosureProtection = 'simple'; |
— | — | @@ -22,10 +22,7 @@ |
23 | 23 | $this->hashLevels = isset( $info['hashLevels'] ) ? $info['hashLevels'] : 2; |
24 | 24 | $this->deletedHashLevels = isset( $info['deletedHashLevels'] ) ? |
25 | 25 | $info['deletedHashLevels'] : $this->hashLevels; |
26 | | - $this->hiddenHashLevels = isset( $info['hiddenHashLevels'] ) ? |
27 | | - $info['hiddenHashLevels'] : $this->hashLevels; |
28 | 26 | $this->deletedDir = isset( $info['deletedDir'] ) ? $info['deletedDir'] : false; |
29 | | - $this->hiddenDir = isset( $info['hiddenDir'] ) ? $info['hiddenDir'] : false; |
30 | 27 | } |
31 | 28 | |
32 | 29 | /** |
— | — | @@ -58,8 +55,6 @@ |
59 | 56 | return $this->directory; |
60 | 57 | case 'temp': |
61 | 58 | return "{$this->directory}/temp"; |
62 | | - case 'hidden': |
63 | | - return $this->hiddenDir; |
64 | 59 | case 'deleted': |
65 | 60 | return $this->deletedDir; |
66 | 61 | default: |
— | — | @@ -76,8 +71,6 @@ |
77 | 72 | return $this->url; |
78 | 73 | case 'temp': |
79 | 74 | return "{$this->url}/temp"; |
80 | | - case 'hidden': |
81 | | - return false; // no public URL |
82 | 75 | case 'deleted': |
83 | 76 | return false; // no public URL |
84 | 77 | default: |
— | — | @@ -424,7 +417,7 @@ |
425 | 418 | $status->error( 'filedeleteerror', $srcPath ); |
426 | 419 | $good = false; |
427 | 420 | } |
428 | | - } else { |
| 421 | + } else{ |
429 | 422 | if ( !@rename( $srcPath, $archivePath ) ) { |
430 | 423 | $status->error( 'filerenameerror', $srcPath, $archivePath ); |
431 | 424 | $good = false; |
Index: trunk/phase3/includes/filerepo/File.php |
— | — | @@ -380,17 +380,6 @@ |
381 | 381 | return $this->getPath() && file_exists( $this->path ); |
382 | 382 | } |
383 | 383 | |
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 | | - |
395 | 384 | function getTransformScript() { |
396 | 385 | if ( !isset( $this->transformScript ) ) { |
397 | 386 | $this->transformScript = false; |
— | — | @@ -611,7 +600,7 @@ |
612 | 601 | * STUB |
613 | 602 | * Overridden by LocalFile |
614 | 603 | */ |
615 | | - function purgeCache() {} |
| 604 | + function purgeCache( $archiveFiles = array() ) {} |
616 | 605 | |
617 | 606 | /** |
618 | 607 | * Purge the file description page, but don't go after |
— | — | @@ -923,13 +912,14 @@ |
924 | 913 | * |
925 | 914 | * May throw database exceptions on error. |
926 | 915 | * |
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. |
928 | 918 | * @return the number of file revisions restored if successful, |
929 | 919 | * or false on failure |
930 | 920 | * STUB |
931 | 921 | * Overridden by LocalFile |
932 | 922 | */ |
933 | | - function restore( $timestamp = 0, $Unsuppress=false ) { |
| 923 | + function restore( $versions=array(), $Unsuppress=false ) { |
934 | 924 | $this->readOnlyError(); |
935 | 925 | } |
936 | 926 | |
Index: trunk/phase3/includes/filerepo/ArchivedFile.php |
— | — | @@ -5,49 +5,24 @@ |
6 | 6 | */ |
7 | 7 | class ArchivedFile |
8 | 8 | { |
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 | | - |
36 | 9 | /** |
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 |
38 | 14 | * @return ResultWrapper |
39 | 15 | */ |
40 | | - function load() { |
41 | | - if( !is_object( $this->title ) ) { |
| 16 | + function ArchivedFile( $title, $id=0, $key='' ) { |
| 17 | + if( !is_object( $title ) ) { |
42 | 18 | throw new MWException( 'ArchivedFile constructor given bogus title.' ); |
43 | 19 | } |
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 ) { |
46 | 22 | $dbr = wfGetDB( DB_SLAVE ); |
47 | 23 | $res = $dbr->select( 'filearchive', |
48 | 24 | array( |
49 | 25 | 'fa_id', |
50 | 26 | 'fa_name', |
51 | | - 'fa_archive_name', |
52 | 27 | 'fa_storage_key', |
53 | 28 | 'fa_storage_group', |
54 | 29 | 'fa_size', |
— | — | @@ -64,7 +39,7 @@ |
65 | 40 | 'fa_timestamp', |
66 | 41 | 'fa_deleted' ), |
67 | 42 | array( |
68 | | - 'fa_name' => $this->title->getDBKey(), |
| 43 | + 'fa_name' => $title->getDbKey(), |
69 | 44 | $conds ), |
70 | 45 | __METHOD__, |
71 | 46 | array( 'ORDER BY' => 'fa_timestamp DESC' ) ); |
— | — | @@ -77,23 +52,22 @@ |
78 | 53 | $row = $ret->fetchObject(); |
79 | 54 | |
80 | 55 | // 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; |
98 | 72 | } else { |
99 | 73 | throw new MWException( 'This title does not correspond to an image page.' ); |
100 | 74 | return; |
— | — | @@ -102,40 +76,12 @@ |
103 | 77 | } |
104 | 78 | |
105 | 79 | /** |
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 | | - /** |
134 | 80 | * int $field one of DELETED_* bitfield constants |
135 | 81 | * for file or revision rows |
136 | 82 | * @return bool |
137 | 83 | */ |
138 | 84 | function isDeleted( $field ) { |
139 | | - return ($this->deleted & $field) == $field; |
| 85 | + return ($this->mDeleted & $field) == $field; |
140 | 86 | } |
141 | 87 | |
142 | 88 | /** |
— | — | @@ -145,16 +91,18 @@ |
146 | 92 | * @return bool |
147 | 93 | */ |
148 | 94 | function userCan( $field ) { |
149 | | - if( isset($this->deleted) && ($this->deleted & $field) == $field ) { |
| 95 | + if( isset($this->mDeleted) && ($this->mDeleted & $field) == $field ) { |
150 | 96 | // images |
151 | 97 | global $wgUser; |
152 | | - $permission = ( $this->deleted & File::DELETED_RESTRICTED ) == File::DELETED_RESTRICTED |
| 98 | + $permission = ( $this->mDeleted & File::DELETED_RESTRICTED ) == File::DELETED_RESTRICTED |
153 | 99 | ? 'hiderevision' |
154 | 100 | : '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" ); |
156 | 102 | return $wgUser->isAllowed( $permission ); |
157 | 103 | } else { |
158 | 104 | return true; |
159 | 105 | } |
160 | 106 | } |
161 | 107 | } |
| 108 | + |
| 109 | + |
Index: trunk/phase3/includes/filerepo/FileRepo.php |
— | — | @@ -6,7 +6,6 @@ |
7 | 7 | */ |
8 | 8 | abstract class FileRepo { |
9 | 9 | const DELETE_SOURCE = 1; |
10 | | - const FIND_PRIVATE = 1; |
11 | 10 | const OVERWRITE = 2; |
12 | 11 | const OVERWRITE_SAME = 4; |
13 | 12 | |
— | — | @@ -77,23 +76,20 @@ |
78 | 77 | * |
79 | 78 | * @param mixed $time 14-character timestamp, or false for the current version |
80 | 79 | */ |
81 | | - function findFile( $title, $time = false, $flags = 0 ) { |
| 80 | + function findFile( $title, $time = false ) { |
82 | 81 | # First try the current version of the file to see if it precedes the timestamp |
83 | 82 | $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 ) ) { |
86 | 87 | return $img; |
87 | 88 | } |
88 | 89 | # Now try an old version of the file |
89 | 90 | $img = $this->newFile( $title, $time ); |
90 | 91 | 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; |
96 | 93 | } |
97 | | - return false; |
98 | 94 | } |
99 | 95 | |
100 | 96 | /** |
Index: trunk/phase3/includes/filerepo/OldLocalFile.php |
— | — | @@ -56,10 +56,6 @@ |
57 | 57 | function isOld() { |
58 | 58 | return true; |
59 | 59 | } |
60 | | - |
61 | | - function isVisible() { |
62 | | - return $this->exists() && !$this->isDeleted(File::DELETED_FILE); |
63 | | - } |
64 | 60 | |
65 | 61 | /** |
66 | 62 | * Try to load file metadata from memcached. Returns true on success. |
— | — | @@ -183,8 +179,10 @@ |
184 | 180 | function getCacheFields( $prefix = 'img_' ) { |
185 | 181 | $fields = parent::getCacheFields( $prefix ); |
186 | 182 | $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' ) ); |
189 | 187 | return $fields; |
190 | 188 | } |
191 | 189 | |
— | — | @@ -228,35 +226,7 @@ |
229 | 227 | ); |
230 | 228 | wfProfileOut( __METHOD__ ); |
231 | 229 | } |
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 | | - |
261 | 230 | } |
262 | 231 | |
263 | 232 | |
| 233 | + |
Index: trunk/phase3/includes/ImagePage.php |
— | — | @@ -416,23 +416,22 @@ |
417 | 417 | |
418 | 418 | if ( $line ) { |
419 | 419 | $list = new ImageHistoryList( $sk, $this->img ); |
420 | | - // Our top image |
421 | 420 | $file = $this->repo->newFileFromRow( $line ); |
422 | 421 | $dims = $file->getDimensionsString(); |
423 | 422 | $s = $list->beginImageHistoryList() . |
424 | 423 | $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 |
428 | 427 | ); |
429 | | - // old image versions |
| 428 | + |
430 | 429 | while ( $line = $this->img->nextHistoryLine() ) { |
431 | 430 | $file = $this->repo->newFileFromRow( $line ); |
432 | 431 | $dims = $file->getDimensionsString(); |
433 | 432 | $s .= $list->imageHistoryLine( false, $line->oi_timestamp, |
434 | 433 | $line->oi_archive_name, $line->oi_user, |
435 | 434 | $line->oi_user_text, $line->oi_size, $line->oi_description, |
436 | | - $dims, $line->oi_deleted, $line->oi_sha1 |
| 435 | + $dims |
437 | 436 | ); |
438 | 437 | } |
439 | 438 | $s .= $list->endImageHistoryList(); |
— | — | @@ -551,7 +550,7 @@ |
552 | 551 | . $wgOut->parse( wfMsgNoTrans( 'filehist-help' ) ) |
553 | 552 | . Xml::openElement( 'table', array( 'class' => 'filehistory' ) ) . "\n" |
554 | 553 | . '<tr><td></td>' |
555 | | - . ( $this->img->isLocal() && $wgUser->isAllowed( 'deleterevision' ) ? '<td></td>' : '' ) |
| 554 | + . ( $this->img->isLocal() && $wgUser->isAllowed( 'delete' ) ? '<td></td>' : '' ) |
556 | 555 | . '<th>' . wfMsgHtml( 'filehist-datetime' ) . '</th>' |
557 | 556 | . '<th>' . wfMsgHtml( 'filehist-user' ) . '</th>' |
558 | 557 | . '<th>' . wfMsgHtml( 'filehist-dimensions' ) . '</th>' |
— | — | @@ -564,48 +563,30 @@ |
565 | 564 | return "</table>\n"; |
566 | 565 | } |
567 | 566 | |
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; |
571 | 569 | $local = $this->img->isLocal(); |
572 | | - $row = '<td>'; |
| 570 | + $row = ''; |
573 | 571 | |
574 | 572 | // Deletion link |
575 | | - if( $iscur && $local && $wgUser->isAllowed( 'delete' ) ) { |
| 573 | + if( $local && $wgUser->isAllowed( 'delete' ) ) { |
| 574 | + $row .= '<td>'; |
576 | 575 | $q = array(); |
577 | 576 | $q[] = 'action=delete'; |
578 | | - $q[] = 'image=' . $this->title->getPartialUrl(); |
| 577 | + if( !$iscur ) |
| 578 | + $q[] = 'oldimage=' . urlencode( $img ); |
579 | 579 | $row .= '(' . $this->skin->makeKnownLinkObj( |
580 | 580 | $this->title, |
581 | 581 | wfMsgHtml( $iscur ? 'filehist-deleteall' : 'filehist-deleteone' ), |
582 | 582 | implode( '&', $q ) |
583 | 583 | ) . ')'; |
584 | | - $row .= '</td><td>'; |
| 584 | + $row .= '</td>'; |
585 | 585 | } |
586 | 586 | |
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 | | - |
605 | 587 | // Reversion link/current indicator |
| 588 | + $row .= '<td>'; |
606 | 589 | 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' ) . ')'; |
610 | 591 | } elseif( $local && $wgUser->isLoggedIn() && $this->title->userCan( 'edit' ) ) { |
611 | 592 | $q = array(); |
612 | 593 | $q[] = 'action=revert'; |
— | — | @@ -621,32 +602,18 @@ |
622 | 603 | |
623 | 604 | // Date/time and image link |
624 | 605 | $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 | + ); |
641 | 612 | $row .= '</td>'; |
642 | 613 | |
643 | 614 | // Uploading user |
644 | 615 | $row .= '<td>'; |
645 | 616 | 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 ); |
651 | 618 | } else { |
652 | 619 | $row .= htmlspecialchars( $usertext ); |
653 | 620 | } |
— | — | @@ -658,45 +625,10 @@ |
659 | 626 | // File size |
660 | 627 | $row .= '<td class="mw-imagepage-filesize">' . $this->skin->formatSize( $size ) . '</td>'; |
661 | 628 | |
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>'; |
667 | 631 | |
668 | 632 | return "<tr>{$row}</tr>\n"; |
669 | 633 | } |
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 | | - } |
702 | 634 | |
703 | 635 | } |
Index: trunk/phase3/includes/SpecialIpblocklist.php |
— | — | @@ -322,13 +322,13 @@ |
323 | 323 | $titleObj = SpecialPage::getTitleFor( "Ipblocklist" ); |
324 | 324 | $unblocklink = ' (' . $sk->makeKnownLinkObj($titleObj, $msg['unblocklink'], 'action=unblock&id=' . urlencode( $block->mId ) ) . ')'; |
325 | 325 | } |
326 | | - |
| 326 | + |
327 | 327 | $comment = $sk->commentBlock( $block->mReason ); |
328 | | - |
| 328 | + |
329 | 329 | $s = "{$line} $comment"; |
330 | 330 | if ( $block->mHideName ) |
331 | 331 | $s = '<span class="history-deleted">' . $s . '</span>'; |
332 | | - |
| 332 | + |
333 | 333 | wfProfileOut( __METHOD__ ); |
334 | 334 | return "<li>$s $unblocklink</li>\n"; |
335 | 335 | } |
Index: trunk/phase3/includes/SpecialLog.php |
— | — | @@ -50,24 +50,7 @@ |
51 | 51 | $this->db = wfGetDB( DB_SLAVE ); |
52 | 52 | $this->setupQuery( $request ); |
53 | 53 | } |
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'; |
63 | 54 | |
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 | | - |
72 | 55 | /** |
73 | 56 | * Basic setup and applies the limiting factors from the WebRequest object. |
74 | 57 | * @param WebRequest $request |
— | — | @@ -97,31 +80,10 @@ |
98 | 81 | |
99 | 82 | /** |
100 | 83 | * Set the log reader to return only entries of the given type. |
101 | | - * Type restrictions enforced here |
102 | 84 | * @param string $type A log type ('upload', 'delete', etc) |
103 | 85 | * @private |
104 | 86 | */ |
105 | 87 | 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 | | - |
126 | 88 | if( empty( $type ) ) { |
127 | 89 | return false; |
128 | 90 | } |
— | — | @@ -199,16 +161,11 @@ |
200 | 162 | * @private |
201 | 163 | */ |
202 | 164 | function getQuery() { |
203 | | - global $wgAllowLogDeletion; |
204 | | - |
205 | 165 | $logging = $this->db->tableName( "logging" ); |
206 | 166 | $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 "; |
213 | 170 | if( !empty( $this->joinClauses ) ) { |
214 | 171 | $sql .= implode( ' ', $this->joinClauses ); |
215 | 172 | } |
— | — | @@ -276,7 +233,7 @@ |
277 | 234 | $this->db->freeResult( $res ); |
278 | 235 | return $ret; |
279 | 236 | } |
280 | | - |
| 237 | + |
281 | 238 | } |
282 | 239 | |
283 | 240 | /** |
— | — | @@ -284,12 +241,8 @@ |
285 | 242 | * @addtogroup SpecialPage |
286 | 243 | */ |
287 | 244 | class LogViewer { |
288 | | - const DELETED_ACTION = 1; |
289 | | - const DELETED_COMMENT = 2; |
290 | | - const DELETED_USER = 4; |
291 | | - const DELETED_RESTRICTED = 8; |
292 | | - |
293 | 245 | const NO_ACTION_LINK = 1; |
| 246 | + |
294 | 247 | /** |
295 | 248 | * @var LogReader $reader |
296 | 249 | */ |
— | — | @@ -306,22 +259,8 @@ |
307 | 260 | global $wgUser; |
308 | 261 | $this->skin = $wgUser->getSkin(); |
309 | 262 | $this->reader =& $reader; |
310 | | - $this->preCacheMessages(); |
311 | 263 | $this->flags = $flags; |
312 | 264 | } |
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 | | - } |
326 | 265 | |
327 | 266 | /** |
328 | 267 | * Take over the whole output page in $wgOut with the log display. |
— | — | @@ -339,84 +278,8 @@ |
340 | 279 | $this->showError( $wgOut ); |
341 | 280 | } |
342 | 281 | } |
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 | | - } |
355 | 282 | |
356 | 283 | /** |
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 | | - /** |
421 | 284 | * Load the data from the linked LogReader |
422 | 285 | * Preload the link cache |
423 | 286 | * Initialise numResults |
— | — | @@ -500,154 +363,54 @@ |
501 | 364 | } else { |
502 | 365 | $linkCache->addBadLinkObj( $title ); |
503 | 366 | } |
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 | | - } |
534 | 367 | |
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 ); |
570 | 371 | $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() ) ) . ')'; |
574 | 389 | |
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 ); |
633 | 406 | } |
| 407 | + # Suppress $comment from old entries, not needed and can contain incorrect links |
| 408 | + $comment = ''; |
634 | 409 | } |
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 | | - } |
649 | 410 | } |
650 | | - $revert = ($revert == '') ? "" : " ($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; |
652 | 415 | } |
653 | 416 | |
654 | 417 | /** |
— | — | @@ -688,8 +451,6 @@ |
689 | 452 | * @private |
690 | 453 | */ |
691 | 454 | function getTypeMenu() { |
692 | | - global $wgLogRestrictions, $wgUser; |
693 | | - |
694 | 455 | $out = "<select name='type'>\n"; |
695 | 456 | |
696 | 457 | $validTypes = LogPage::validTypes(); |
— | — | @@ -707,14 +468,7 @@ |
708 | 469 | // Third pass generates sorted XHTML content |
709 | 470 | foreach( $m as $text => $type ) { |
710 | 471 | $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"; |
719 | 473 | } |
720 | 474 | |
721 | 475 | $out .= '</select>'; |
— | — | @@ -770,41 +524,7 @@ |
771 | 525 | $this->numResults < $limit); |
772 | 526 | $out->addHTML( '<p>' . $html . '</p>' ); |
773 | 527 | } |
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 | | - } |
801 | 528 | } |
802 | 529 | |
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 ); |
810 | 530 | |
811 | 531 | |
Index: trunk/phase3/includes/SpecialUndelete.php |
— | — | @@ -78,7 +78,7 @@ |
79 | 79 | array( |
80 | 80 | 'ar_namespace', |
81 | 81 | 'ar_title', |
82 | | - 'COUNT(*) AS count' |
| 82 | + 'COUNT(*) AS count', |
83 | 83 | ), |
84 | 84 | $condition, |
85 | 85 | __METHOD__, |
— | — | @@ -92,6 +92,24 @@ |
93 | 93 | } |
94 | 94 | |
95 | 95 | /** |
| 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 | + /** |
96 | 114 | * List the deleted file revisions for this page, if it's a file page. |
97 | 115 | * Returns a result wrapper with various filearchive fields, or null |
98 | 116 | * if not a file page. |
— | — | @@ -106,22 +124,14 @@ |
107 | 125 | array( |
108 | 126 | 'fa_id', |
109 | 127 | 'fa_name', |
110 | | - 'fa_archive_name', |
111 | 128 | 'fa_storage_key', |
112 | | - 'fa_storage_group', |
113 | 129 | 'fa_size', |
114 | 130 | 'fa_width', |
115 | 131 | 'fa_height', |
116 | | - 'fa_bits', |
117 | | - 'fa_metadata', |
118 | | - 'fa_media_type', |
119 | | - 'fa_major_mime', |
120 | | - 'fa_minor_mime', |
121 | 132 | 'fa_description', |
122 | 133 | 'fa_user', |
123 | 134 | 'fa_user_text', |
124 | | - 'fa_timestamp', |
125 | | - 'fa_deleted' ), |
| 135 | + 'fa_timestamp' ), |
126 | 136 | array( 'fa_name' => $this->title->getDbKey() ), |
127 | 137 | __METHOD__, |
128 | 138 | array( 'ORDER BY' => 'fa_timestamp DESC' ) ); |
— | — | @@ -142,25 +152,14 @@ |
143 | 153 | $rev = $this->getRevision( $timestamp ); |
144 | 154 | return $rev ? $rev->getText() : null; |
145 | 155 | } |
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 | | - } |
157 | 156 | |
158 | 157 | /** |
159 | 158 | * 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 |
162 | 161 | * @return Revision |
163 | 162 | */ |
164 | | - function getRevision( $timestamp, $id=null ) { |
| 163 | + function getRevision( $timestamp ) { |
165 | 164 | $dbr = wfGetDB( DB_SLAVE ); |
166 | 165 | $row = $dbr->selectRow( 'archive', |
167 | 166 | array( |
— | — | @@ -173,11 +172,10 @@ |
174 | 173 | 'ar_minor_edit', |
175 | 174 | 'ar_flags', |
176 | 175 | 'ar_text_id', |
177 | | - 'ar_deleted', |
178 | 176 | 'ar_len' ), |
179 | 177 | array( 'ar_namespace' => $this->title->getNamespace(), |
180 | 178 | 'ar_title' => $this->title->getDbkey(), |
181 | | - $this->getRevisionConds( $dbr->timestamp($timestamp), $id ) ), |
| 179 | + 'ar_timestamp' => $dbr->timestamp( $timestamp ) ), |
182 | 180 | __METHOD__ ); |
183 | 181 | if( $row ) { |
184 | 182 | return new Revision( array( |
— | — | @@ -191,9 +189,7 @@ |
192 | 190 | 'user_text' => $row->ar_user_text, |
193 | 191 | 'timestamp' => $row->ar_timestamp, |
194 | 192 | '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 ) ); |
198 | 194 | } else { |
199 | 195 | return null; |
200 | 196 | } |
— | — | @@ -258,50 +254,48 @@ |
259 | 255 | * Restore the given (or all) text and file revisions for the page. |
260 | 256 | * Once restored, the items will be removed from the archive tables. |
261 | 257 | * 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 |
263 | 258 | * |
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. |
265 | 260 | * @param string $comment |
266 | | - * @param string $filetimestamp, restore all revision from this time on |
267 | | - * @param bool $Unsuppress |
| 261 | + * @param array $fileVersions |
268 | 262 | * |
269 | 263 | * @return true on success. |
270 | 264 | */ |
271 | | - function undelete( $pagetimestamp = 0, $comment = '', $filetimestamp = 0, $Unsuppress = false) { |
| 265 | + function undelete( $timestamps, $comment = '', $fileVersions = array() ) { |
272 | 266 | // If both the set of text revisions and file revisions are empty, |
273 | 267 | // restore everything. Otherwise, just restore the requested items. |
274 | | - $restoreAll = ($pagetimestamp==0 && $filetimestamp==0); |
| 268 | + $restoreAll = empty( $timestamps ) && empty( $fileVersions ); |
275 | 269 | |
276 | | - $restoreText = ($restoreAll || $pagetimestamp ); |
277 | | - $restoreFiles = ($restoreAll || $filetimestamp ); |
| 270 | + $restoreText = $restoreAll || !empty( $timestamps ); |
| 271 | + $restoreFiles = $restoreAll || !empty( $fileVersions ); |
278 | 272 | |
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 ) { |
286 | 274 | $img = wfLocalFile( $this->title ); |
287 | | - $this->fileStatus = $img->restore( $filetimestamp, $Unsuppress ); |
| 275 | + $this->fileStatus = $img->restore( $fileVersions ); |
288 | 276 | $filesRestored = $this->fileStatus->successCount; |
289 | 277 | } else { |
290 | 278 | $filesRestored = 0; |
291 | 279 | } |
| 280 | + |
| 281 | + if( $restoreText ) { |
| 282 | + $textRestored = $this->undeleteRevisions( $timestamps ); |
| 283 | + } else { |
| 284 | + $textRestored = 0; |
| 285 | + } |
292 | 286 | |
293 | 287 | // Touch the log! |
294 | 288 | global $wgContLang; |
295 | 289 | $log = new LogPage( 'delete' ); |
296 | 290 | |
297 | 291 | if( $textRestored && $filesRestored ) { |
298 | | - $reason = wfMsgExt( 'undeletedrevisions-files', array('parsemag'), |
| 292 | + $reason = wfMsgForContent( 'undeletedrevisions-files', |
299 | 293 | $wgContLang->formatNum( $textRestored ), |
300 | 294 | $wgContLang->formatNum( $filesRestored ) ); |
301 | 295 | } elseif( $textRestored ) { |
302 | | - $reason = wfMsgExt( 'undeletedrevisions', array('parsemag'), |
| 296 | + $reason = wfMsgForContent( 'undeletedrevisions', |
303 | 297 | $wgContLang->formatNum( $textRestored ) ); |
304 | 298 | } elseif( $filesRestored ) { |
305 | | - $reason = wfMsgExt( 'undeletedfiles', array('parsemag'), |
| 299 | + $reason = wfMsgForContent( 'undeletedfiles', |
306 | 300 | $wgContLang->formatNum( $filesRestored ) ); |
307 | 301 | } else { |
308 | 302 | wfDebug( "Undelete: nothing undeleted...\n" ); |
— | — | @@ -310,7 +304,7 @@ |
311 | 305 | |
312 | 306 | if( trim( $comment ) != '' ) |
313 | 307 | $reason .= ": {$comment}"; |
314 | | - $log->addEntry( 'restore', $this->title, $reason, array($pagetimestamp,$filetimestamp) ); |
| 308 | + $log->addEntry( 'restore', $this->title, $reason ); |
315 | 309 | |
316 | 310 | if ( $this->fileStatus && !$this->fileStatus->ok ) { |
317 | 311 | return false; |
— | — | @@ -324,73 +318,52 @@ |
325 | 319 | * to the cur/old tables. If the page currently exists, all revisions will |
326 | 320 | * be stuffed into old, otherwise the most recent will go into cur. |
327 | 321 | * |
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. |
329 | 323 | * @param string $comment |
330 | 324 | * @param array $fileVersions |
331 | | - * @param bool $Unsuppress, remove all ar_deleted/fa_deleted restrictions of seletected revs |
332 | 325 | * |
333 | 326 | * @return int number of revisions restored |
334 | 327 | */ |
335 | | - private function undeleteRevisions( $timestamp, $Unsuppress = false ) { |
336 | | - $restoreAll = ($timestamp==0); |
| 328 | + private function undeleteRevisions( $timestamps ) { |
| 329 | + $restoreAll = empty( $timestamps ); |
337 | 330 | |
338 | 331 | $dbw = wfGetDB( DB_MASTER ); |
339 | | - $makepage = false; // Do we need to make a new page? |
340 | 332 | |
341 | 333 | # Does this page already exist? We'll have to update it... |
342 | 334 | $article = new Article( $this->title ); |
343 | 335 | $options = 'FOR UPDATE'; |
344 | 336 | $page = $dbw->selectRow( 'page', |
345 | 337 | 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() ), |
348 | 340 | __METHOD__, |
349 | 341 | $options ); |
350 | | - |
351 | 342 | if( $page ) { |
352 | 343 | # Page already exists. Import the history, and if necessary |
353 | 344 | # we'll update the latest revision field in the record. |
354 | 345 | $newid = 0; |
355 | 346 | $pageId = $page->page_id; |
356 | 347 | $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 | | - |
379 | 348 | } else { |
380 | 349 | # Have to create a new article... |
381 | | - $makepage = true; |
| 350 | + $newid = $article->insertOn( $dbw ); |
| 351 | + $pageId = $newid; |
382 | 352 | $previousRevId = 0; |
383 | | - $previousTimestamp = 0; |
384 | 353 | } |
385 | 354 | |
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} )"; |
391 | 364 | } |
392 | 365 | |
393 | 366 | /** |
394 | | - * Select each archived revision... |
| 367 | + * Restore each revision... |
395 | 368 | */ |
396 | 369 | $result = $dbw->select( 'archive', |
397 | 370 | /* fields */ array( |
— | — | @@ -403,40 +376,24 @@ |
404 | 377 | 'ar_minor_edit', |
405 | 378 | 'ar_flags', |
406 | 379 | 'ar_text_id', |
407 | | - 'ar_deleted', |
408 | 380 | 'ar_len' ), |
409 | | - /* WHERE */ |
410 | | - $conditions, |
| 381 | + /* WHERE */ array( |
| 382 | + 'ar_namespace' => $this->title->getNamespace(), |
| 383 | + 'ar_title' => $this->title->getDBkey(), |
| 384 | + $oldones ), |
411 | 385 | __METHOD__, |
412 | 386 | /* options */ array( |
413 | 387 | 'ORDER BY' => 'ar_timestamp' ) |
414 | 388 | ); |
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; |
430 | 392 | } |
431 | 393 | |
432 | | - if( $makepage ) { |
433 | | - $newid = $article->insertOn( $dbw ); |
434 | | - $pageId = $newid; |
435 | | - } |
436 | | - |
437 | 394 | $revision = null; |
438 | 395 | $restored = 0; |
439 | | - |
440 | | - while( $row = $ret->fetchObject() ) { |
| 396 | + |
| 397 | + while( $row = $dbw->fetchObject( $result ) ) { |
441 | 398 | if( $row->ar_text_id ) { |
442 | 399 | // Revision was deleted in 1.5+; text is in |
443 | 400 | // the regular text table, use the reference. |
— | — | @@ -459,14 +416,12 @@ |
460 | 417 | 'timestamp' => $row->ar_timestamp, |
461 | 418 | 'minor_edit' => $row->ar_minor_edit, |
462 | 419 | 'text_id' => $row->ar_text_id, |
463 | | - 'deleted' => $Unsuppress ? 0 : $row->ar_deleted, |
464 | | - 'len' => $row->ar_len |
| 420 | + 'len' => $row->ar_len |
465 | 421 | ) ); |
466 | 422 | $revision->insertOn( $dbw ); |
467 | 423 | $restored++; |
468 | 424 | } |
469 | | - |
470 | | - # If there were any revisions restored... |
| 425 | + |
471 | 426 | if( $revision ) { |
472 | 427 | // Attach the latest revision to the page... |
473 | 428 | $wasnew = $article->updateIfNewerOn( $dbw, $revision, $previousRevId ); |
— | — | @@ -475,7 +430,7 @@ |
476 | 431 | // Update site stats, link tables, etc |
477 | 432 | $article->createUpdates( $revision ); |
478 | 433 | } |
479 | | - |
| 434 | + |
480 | 435 | if( $newid ) { |
481 | 436 | wfRunHooks( 'ArticleUndelete', array( &$this->title, true ) ); |
482 | 437 | Article::onArticleCreate( $this->title ); |
— | — | @@ -483,22 +438,17 @@ |
484 | 439 | wfRunHooks( 'ArticleUndelete', array( &$this->title, false ) ); |
485 | 440 | Article::onArticleEdit( $this->title ); |
486 | 441 | } |
| 442 | + } else { |
| 443 | + # Something went terribly wrong! |
487 | 444 | } |
488 | 445 | |
489 | 446 | # Now that it's safely stored, take it out of the archive |
490 | 447 | $dbw->delete( 'archive', |
491 | | - /* WHERE */ |
492 | | - $conditions, |
| 448 | + /* WHERE */ array( |
| 449 | + 'ar_namespace' => $this->title->getNamespace(), |
| 450 | + 'ar_title' => $this->title->getDBkey(), |
| 451 | + $oldones ), |
493 | 452 | __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__ ); |
503 | 453 | |
504 | 454 | return $restored; |
505 | 455 | } |
— | — | @@ -523,92 +473,71 @@ |
524 | 474 | $time = $request->getVal( 'timestamp' ); |
525 | 475 | $this->mTimestamp = $time ? wfTimestamp( TS_MW, $time ) : ''; |
526 | 476 | $this->mFile = $request->getVal( 'file' ); |
527 | | - $this->mDiff = $request->getVal( 'diff' ); |
528 | | - $this->mOldid = $request->getVal( 'oldid' ); |
529 | 477 | |
530 | | - $posted = $request->wasPosted() && $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) ); |
| 478 | + $posted = $request->wasPosted() && |
| 479 | + $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) ); |
531 | 480 | $this->mRestore = $request->getCheck( 'restore' ) && $posted; |
532 | 481 | $this->mPreview = $request->getCheck( 'preview' ) && $posted; |
533 | 482 | $this->mComment = $request->getText( 'wpComment' ); |
534 | | - $this->mUnsuppress = $request->getVal( 'wpUnsuppress' ) && $wgUser->isAllowed( 'oversight' ); |
535 | 483 | |
536 | 484 | if( $par != "" ) { |
537 | 485 | $this->mTarget = $par; |
538 | | - $_GET['target'] = $par; // hack for Pager |
539 | 486 | } |
540 | | - if( $wgUser->isAllowed( 'delete' ) && !$wgUser->isBlocked() ) { |
| 487 | + if ( $wgUser->isAllowed( 'delete' ) && !$wgUser->isBlocked() ) { |
541 | 488 | $this->mAllowed = true; |
542 | 489 | } else { |
543 | 490 | $this->mAllowed = false; |
544 | 491 | $this->mTimestamp = ''; |
545 | 492 | $this->mRestore = false; |
546 | 493 | } |
547 | | - if( $this->mTarget !== "" ) { |
| 494 | + if ( $this->mTarget !== "" ) { |
548 | 495 | $this->mTargetObj = Title::newFromURL( $this->mTarget ); |
549 | 496 | } else { |
550 | 497 | $this->mTargetObj = NULL; |
551 | 498 | } |
552 | 499 | 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 | + } |
568 | 511 | } |
| 512 | + rsort( $timestamps ); |
| 513 | + $this->mTargetTimestamp = $timestamps; |
569 | 514 | } |
570 | 515 | } |
571 | 516 | |
572 | 517 | 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" ) ); |
576 | 521 | } else { |
577 | | - $wgOut->setPagetitle( wfMsgHtml( "viewdeletedpage" ) ); |
| 522 | + $wgOut->setPagetitle( wfMsg( "viewdeletedpage" ) ); |
578 | 523 | } |
579 | 524 | |
580 | 525 | 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(); |
584 | 527 | |
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 ); |
592 | 533 | } |
593 | 534 | return; |
594 | 535 | } |
595 | 536 | if( $this->mTimestamp !== '' ) { |
596 | 537 | return $this->showRevision( $this->mTimestamp ); |
597 | 538 | } |
598 | | - |
599 | | - if( $this->mDiff && $this->mOldid ) |
600 | | - return $this->showDiff( $this->mDiff, $this->mOldid ); |
601 | | - |
602 | 539 | 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 ); |
611 | 541 | } |
612 | | - |
613 | 542 | if( $this->mRestore && $this->mAction == "submit" ) { |
614 | 543 | return $this->undelete(); |
615 | 544 | } |
— | — | @@ -636,8 +565,7 @@ |
637 | 566 | '</form>' ); |
638 | 567 | } |
639 | 568 | |
640 | | - // Generic list of deleted pages |
641 | | - private function showList( $result ) { |
| 569 | + /* private */ function showList( $result ) { |
642 | 570 | global $wgLang, $wgContLang, $wgUser, $wgOut; |
643 | 571 | |
644 | 572 | if( $result->numRows() == 0 ) { |
— | — | @@ -665,7 +593,7 @@ |
666 | 594 | return true; |
667 | 595 | } |
668 | 596 | |
669 | | - private function showRevision( $timestamp ) { |
| 597 | + /* private */ function showRevision( $timestamp ) { |
670 | 598 | global $wgLang, $wgUser, $wgOut; |
671 | 599 | $self = SpecialPage::getTitleFor( 'Undelete' ); |
672 | 600 | $skin = $wgUser->getSkin(); |
— | — | @@ -676,24 +604,14 @@ |
677 | 605 | $rev = $archive->getRevision( $timestamp ); |
678 | 606 | |
679 | 607 | if( !$rev ) { |
680 | | - $wgOut->addWikiText( wfMsg( 'undeleterevision-missing' ) ); |
| 608 | + $wgOut->addWikiTexT( wfMsg( 'undeleterevision-missing' ) ); |
681 | 609 | return; |
682 | 610 | } |
683 | 611 | |
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 | | - |
695 | 612 | $wgOut->setPageTitle( wfMsg( 'undeletepage' ) ); |
696 | 613 | |
697 | | - $link = $skin->makeKnownLinkObj( $self, |
| 614 | + $link = $skin->makeKnownLinkObj( |
| 615 | + $self, |
698 | 616 | htmlspecialchars( $this->mTargetObj->getPrefixedText() ), |
699 | 617 | 'target=' . $this->mTargetObj->getPrefixedUrl() |
700 | 618 | ); |
— | — | @@ -707,7 +625,7 @@ |
708 | 626 | |
709 | 627 | if( $this->mPreview ) { |
710 | 628 | $wgOut->addHtml( "<hr />\n" ); |
711 | | - $wgOut->addWikiTextTitleTidy( $rev->revText(), $this->mTargetObj, false ); |
| 629 | + $wgOut->addWikiTextTitleTidy( $rev->getText(), $this->mTargetObj, false ); |
712 | 630 | } |
713 | 631 | |
714 | 632 | $wgOut->addHtml( |
— | — | @@ -715,7 +633,7 @@ |
716 | 634 | 'readonly' => 'readonly', |
717 | 635 | 'cols' => intval( $wgUser->getOption( 'cols' ) ), |
718 | 636 | 'rows' => intval( $wgUser->getOption( 'rows' ) ) ), |
719 | | - $rev->revText() . "\n" ) . |
| 637 | + $rev->getText() . "\n" ) . |
720 | 638 | wfOpenElement( 'div' ) . |
721 | 639 | wfOpenElement( 'form', array( |
722 | 640 | 'method' => 'post', |
— | — | @@ -742,74 +660,11 @@ |
743 | 661 | wfCloseElement( 'form' ) . |
744 | 662 | wfCloseElement( 'div' ) ); |
745 | 663 | } |
746 | | - |
747 | | - /** |
748 | | - * Show the changes between two deleted revisions |
749 | | - */ |
750 | | - private function showDiff( $newid, $oldid ) { |
751 | | - global $wgOut, $wgUser, $wgLang; |
752 | 664 | |
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 | | - |
810 | 665 | /** |
811 | 666 | * Show a deleted file version requested by the visitor. |
812 | 667 | */ |
813 | | - private function showFile( $key ) { |
| 668 | + function showFile( $key ) { |
814 | 669 | global $wgOut, $wgRequest; |
815 | 670 | $wgOut->disable(); |
816 | 671 | |
— | — | @@ -825,35 +680,47 @@ |
826 | 681 | $store->stream( $key ); |
827 | 682 | } |
828 | 683 | |
829 | | - private function showHistory() { |
| 684 | + /* private */ function showHistory() { |
830 | 685 | global $wgLang, $wgContLang, $wgUser, $wgOut; |
831 | 686 | |
832 | | - $this->sk = $wgUser->getSkin(); |
833 | | - if( $this->mAllowed ) { |
| 687 | + $sk = $wgUser->getSkin(); |
| 688 | + if ( $this->mAllowed ) { |
834 | 689 | $wgOut->setPagetitle( wfMsg( "undeletepage" ) ); |
835 | 690 | } else { |
836 | 691 | $wgOut->setPagetitle( wfMsg( 'viewdeletedpage' ) ); |
837 | 692 | } |
838 | | - |
839 | | - $wgOut->addWikiText( wfMsgHtml( 'undeletepagetitle', $this->mTargetObj->getPrefixedText()) ); |
840 | 693 | |
841 | 694 | $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" ) ); |
846 | 704 | } else { |
847 | | - $wgOut->addWikiText( wfMsgHtml( "undeletehistorynoadmin" ) ); |
| 705 | + $wgOut->addWikiText( wfMsg( "undeletehistorynoadmin" ) ); |
848 | 706 | } |
849 | 707 | |
850 | 708 | # List all stored revisions |
851 | | - $revisions = new UndeleteRevisionsPager( $this, array(), $this->mTargetObj ); |
| 709 | + $revisions = $archive->listRevisions(); |
852 | 710 | $files = $archive->listFiles(); |
853 | 711 | |
854 | | - $haveRevisions = $revisions && $revisions->getNumRows() > 0; |
| 712 | + $haveRevisions = $revisions && $revisions->numRows() > 0; |
855 | 713 | $haveFiles = $files && $files->numRows() > 0; |
856 | 714 | |
857 | 715 | # 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 | + } |
858 | 725 | if( $haveFiles ) { |
859 | 726 | $batch = new LinkBatch(); |
860 | 727 | while( $row = $files->fetchObject() ) { |
— | — | @@ -864,7 +731,7 @@ |
865 | 732 | $files->seek( 0 ); |
866 | 733 | } |
867 | 734 | |
868 | | - if( $this->mAllowed ) { |
| 735 | + if ( $this->mAllowed ) { |
869 | 736 | $titleObj = SpecialPage::getTitleFor( "Undelete" ); |
870 | 737 | $action = $titleObj->getLocalURL( "action=submit" ); |
871 | 738 | # Start the form here |
— | — | @@ -872,6 +739,20 @@ |
873 | 740 | $wgOut->addHtml( $top ); |
874 | 741 | } |
875 | 742 | |
| 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 | + |
876 | 757 | if( $this->mAllowed && ( $haveRevisions || $haveFiles ) ) { |
877 | 758 | # Format the user-visible controls (comment field, submission button) |
878 | 759 | # in a nice little table |
— | — | @@ -897,10 +778,6 @@ |
898 | 779 | <td>" . |
899 | 780 | Xml::submitButton( wfMsg( 'undeletebtn' ), array( 'name' => 'restore', 'id' => 'mw-undelete-submit' ) ) . |
900 | 781 | 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' ) . |
905 | 782 | "</td> |
906 | 783 | </tr>" . |
907 | 784 | Xml::closeElement( 'table' ) . |
— | — | @@ -909,38 +786,59 @@ |
910 | 787 | $wgOut->addHtml( $table ); |
911 | 788 | } |
912 | 789 | |
913 | | - $wgOut->addHTML( "<h2 id=\"pagehistory\">" . wfMsgHtml( "history" ) . "</h2>\n" ); |
| 790 | + $wgOut->addHTML( "<h2>" . htmlspecialchars( wfMsg( "history" ) ) . "</h2>\n" ); |
914 | 791 | |
915 | 792 | 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×tamp=$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>"); |
923 | 822 | } else { |
924 | 823 | $wgOut->addWikiText( wfMsg( "nohistory" ) ); |
925 | 824 | } |
| 825 | + |
926 | 826 | 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" ); |
929 | 828 | $wgOut->addHtml( "<ul>" ); |
930 | | - $wgOut->addHTML( "<li>" . wfRadio( "imgrestorepoint", -1, false ) . " " . wfMsgHtml('restorenone') . "</li>" ); |
931 | 829 | while( $row = $files->fetchObject() ) { |
932 | | - $file = ArchivedFile::newFromRow( $row ); |
933 | | - |
934 | 830 | $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 ); |
937 | 833 | $key = urlencode( $row->fa_storage_key ); |
938 | 834 | $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" ); |
940 | 838 | } else { |
941 | 839 | $checkBox = ''; |
942 | 840 | $pageLink = $wgLang->timeanddate( $ts, true ); |
943 | 841 | } |
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 ); |
945 | 843 | $data = |
946 | 844 | wfMsgHtml( 'widthheight', |
947 | 845 | $wgLang->formatNum( $row->fa_width ), |
— | — | @@ -948,40 +846,14 @@ |
949 | 847 | ' (' . |
950 | 848 | wfMsgHtml( 'nbytes', $wgLang->formatNum( $row->fa_size ) ) . |
951 | 849 | ')'; |
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" ); |
971 | 852 | } |
972 | 853 | $files->free(); |
973 | 854 | $wgOut->addHTML( "</ul>" ); |
974 | 855 | } |
975 | 856 | |
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 ) { |
986 | 858 | # Slip in the hidden controls here |
987 | 859 | $misc = Xml::hidden( 'target', $this->mTarget ); |
988 | 860 | $misc .= Xml::hidden( 'wpEditToken', $wgUser->editToken() ); |
— | — | @@ -991,152 +863,23 @@ |
992 | 864 | |
993 | 865 | return true; |
994 | 866 | } |
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 | | - } |
1058 | 867 | |
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×tamp=$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 | | - |
1124 | 868 | function undelete() { |
1125 | 869 | global $wgOut, $wgUser; |
1126 | 870 | if( !is_null( $this->mTargetObj ) ) { |
1127 | 871 | $archive = new PageArchive( $this->mTargetObj ); |
1128 | 872 | |
1129 | 873 | $ok = $archive->undelete( |
1130 | | - $this->mPageTimestamp, |
| 874 | + $this->mTargetTimestamp, |
1131 | 875 | $this->mComment, |
1132 | | - $this->mFileTimestamp, |
1133 | | - $this->mUnsuppress ); |
| 876 | + $this->mFileVersions ); |
| 877 | + |
1134 | 878 | if( $ok ) { |
1135 | 879 | $skin = $wgUser->getSkin(); |
1136 | | - $link = $skin->makeKnownLinkObj( $this->mTargetObj, $this->mTargetObj->getPrefixedText(), 'redirect=no' ); |
| 880 | + $link = $skin->makeKnownLinkObj( $this->mTargetObj ); |
1137 | 881 | $wgOut->addHtml( wfMsgWikiHtml( 'undeletedpage', $link ) ); |
1138 | 882 | } else { |
1139 | 883 | $wgOut->showFatalError( wfMsg( "cannotundelete" ) ); |
1140 | | - $wgOut->addHtml( '<p>' . wfMsgHtml( "undeleterevdel" ) . '</p>' ); |
1141 | 884 | } |
1142 | 885 | |
1143 | 886 | // Show file deletion warnings and errors |
— | — | @@ -1151,61 +894,4 @@ |
1152 | 895 | } |
1153 | 896 | } |
1154 | 897 | |
1155 | | -class UndeleteRevisionsPager extends ReverseChronologicalPager { |
1156 | | - public $mForm, $mConds; |
1157 | 898 | |
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 @@ |
443 | 443 | * @param boolean $thumb shows image as thumbnail in a frame |
444 | 444 | * @param string $manualthumb image name for the manual thumbnail |
445 | 445 | * @param string $valign vertical alignment: baseline, sub, super, top, text-top, middle, bottom, text-bottom |
446 | | - * @param string $time, timestamp (for image versioning) |
447 | 446 | * @return string |
448 | 447 | */ |
449 | 448 | function makeImageLinkObj( $title, $label, $alt, $align = '', $handlerParams = array(), $framed = false, |
— | — | @@ -872,13 +871,10 @@ |
873 | 872 | /** |
874 | 873 | * Generate a user link if the current user is allowed to view it |
875 | 874 | * @param $rev Revision object. |
876 | | - * @param $isPublic, bool, show only if all users can see it |
877 | 875 | * @return string HTML |
878 | 876 | */ |
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 ) ) { |
883 | 879 | $link = $this->userLink( $rev->getRawUser(), $rev->getRawUserText() ); |
884 | 880 | } else { |
885 | 881 | $link = wfMsgHtml( 'rev-deleted-user' ); |
— | — | @@ -888,74 +884,21 @@ |
889 | 885 | } |
890 | 886 | return $link; |
891 | 887 | } |
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 | | - } |
917 | 888 | |
918 | 889 | /** |
919 | 890 | * Generate a user tool link cluster if the current user is allowed to view it |
920 | 891 | * @param $rev Revision object. |
921 | | - * @param $isPublic, bool, show only if all users can see it |
922 | 892 | * @return string HTML |
923 | 893 | */ |
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 ) ) { |
928 | 896 | $link = $this->userLink( $rev->getRawUser(), $rev->getRawUserText() ) . |
929 | | - ' ' . $this->userToolLinks( $rev->getRawUser(), $rev->getRawUserText() ); |
| 897 | + ' ' . |
| 898 | + $this->userToolLinks( $rev->getRawUser(), $rev->getRawUserText() ); |
930 | 899 | } else { |
931 | 900 | $link = wfMsgHtml( 'rev-deleted-user' ); |
932 | 901 | } |
933 | 902 | 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 ) ) { |
960 | 903 | return '<span class="history-deleted">' . $link . '</span>'; |
961 | 904 | } |
962 | 905 | return $link; |
— | — | @@ -1113,43 +1056,20 @@ |
1114 | 1057 | * |
1115 | 1058 | * @param Revision $rev |
1116 | 1059 | * @param bool $local Whether section links should refer to local page |
1117 | | - * @param $isPublic, show only if all users can see it |
1118 | 1060 | * @return string HTML |
1119 | 1061 | */ |
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 ) ) { |
1124 | 1064 | $block = $this->commentBlock( $rev->getRawComment(), $rev->getTitle(), $local ); |
1125 | 1065 | } else { |
1126 | | - $block = " <span class=\"comment\">" . wfMsgHtml( 'rev-deleted-comment' ) . "</span>"; |
| 1066 | + $block = " <span class=\"comment\">" . |
| 1067 | + wfMsgHtml( 'rev-deleted-comment' ) . "</span>"; |
1127 | 1068 | } |
1128 | 1069 | if( $rev->isDeleted( Revision::DELETED_COMMENT ) ) { |
1129 | 1070 | return " <span class=\"history-deleted\">$block</span>"; |
1130 | 1071 | } |
1131 | 1072 | return $block; |
1132 | 1073 | } |
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 | | - } |
1154 | 1074 | |
1155 | 1075 | /** @todo document */ |
1156 | 1076 | function tocIndent() { |
Index: trunk/phase3/includes/DefaultSettings.php |
— | — | @@ -170,16 +170,10 @@ |
171 | 171 | * $wgFileStore['deleted']['directory'] = '/var/wiki/private/deleted'; |
172 | 172 | * |
173 | 173 | */ |
174 | | -// For deleted images, gererally were all versions of the image are discarded |
175 | 174 | $wgFileStore = array(); |
176 | 175 | $wgFileStore['deleted']['directory'] = false;// Defaults to $wgUploadDirectory/deleted |
177 | 176 | $wgFileStore['deleted']['url'] = null; // Private |
178 | 177 | $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 |
184 | 178 | |
185 | 179 | /**#@+ |
186 | 180 | * File repository structures |
— | — | @@ -1066,7 +1060,6 @@ |
1067 | 1061 | $wgGroupPermissions['sysop']['block'] = true; |
1068 | 1062 | $wgGroupPermissions['sysop']['createaccount'] = true; |
1069 | 1063 | $wgGroupPermissions['sysop']['delete'] = true; |
1070 | | -$wgGroupPermissions['sysop']['browsearchive'] = true; // can see the deleted page list |
1071 | 1064 | $wgGroupPermissions['sysop']['deletedhistory'] = true; // can view deleted history entries, but not see or restore the text |
1072 | 1065 | $wgGroupPermissions['sysop']['editinterface'] = true; |
1073 | 1066 | $wgGroupPermissions['sysop']['editusercssjs'] = true; |
— | — | @@ -1086,22 +1079,15 @@ |
1087 | 1080 | $wgGroupPermissions['sysop']['autoconfirmed'] = true; |
1088 | 1081 | $wgGroupPermissions['sysop']['upload_by_url'] = true; |
1089 | 1082 | $wgGroupPermissions['sysop']['ipblock-exempt'] = true; |
1090 | | -$wgGroupPermissions['sysop']['deleterevision'] = true; |
1091 | 1083 | $wgGroupPermissions['sysop']['blockemail'] = true; |
1092 | | -$wgGroupPermissions['sysop']['mergehistory'] = true; |
1093 | 1084 | |
1094 | 1085 | // Permission to change users' group assignments |
1095 | 1086 | $wgGroupPermissions['bureaucrat']['userrights'] = true; |
1096 | 1087 | |
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; |
1103 | 1091 | |
1104 | | -$wgAllowLogDeletion = false; |
1105 | | - |
1106 | 1092 | /** |
1107 | 1093 | * The developer group is deprecated, but can be activated if need be |
1108 | 1094 | * to use the 'lockdb' and 'unlockdb' special pages. Those require |
— | — | @@ -2257,21 +2243,9 @@ |
2258 | 2244 | 'move', |
2259 | 2245 | 'import', |
2260 | 2246 | 'patrol', |
2261 | | - 'merge', |
2262 | | - 'oversight', |
2263 | 2247 | ); |
2264 | 2248 | |
2265 | 2249 | /** |
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 | | -/** |
2276 | 2250 | * Lists the message key string for each log type. The localized messages |
2277 | 2251 | * will be listed in the user interface. |
2278 | 2252 | * |
— | — | @@ -2287,8 +2261,6 @@ |
2288 | 2262 | 'move' => 'movelogpage', |
2289 | 2263 | 'import' => 'importlogpage', |
2290 | 2264 | 'patrol' => 'patrol-log-page', |
2291 | | - 'merge' => 'mergelog', |
2292 | | - 'oversight' => 'oversightlog', |
2293 | 2265 | ); |
2294 | 2266 | |
2295 | 2267 | /** |
— | — | @@ -2307,8 +2279,6 @@ |
2308 | 2280 | 'move' => 'movelogpagetext', |
2309 | 2281 | 'import' => 'importlogpagetext', |
2310 | 2282 | 'patrol' => 'patrol-log-header', |
2311 | | - 'merge' => 'mergelogpagetext', |
2312 | | - 'oversight' => 'overlogpagetext', |
2313 | 2283 | ); |
2314 | 2284 | |
2315 | 2285 | /** |
— | — | @@ -2318,29 +2288,22 @@ |
2319 | 2289 | * Extensions with custom log types may add to this array. |
2320 | 2290 | */ |
2321 | 2291 | $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', |
2345 | 2308 | ); |
2346 | 2309 | |
2347 | 2310 | /** |
Index: trunk/phase3/includes/SpecialBlockip.php |
— | — | @@ -227,35 +227,34 @@ |
228 | 228 | </td> |
229 | 229 | </tr> |
230 | 230 | "); |
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' ) ) { |
234 | 233 | $wgOut->addHTML(" |
235 | 234 | <tr> |
236 | 235 | <td> </td> |
237 | 236 | <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' ) ) . " |
241 | 240 | </td> |
242 | 241 | </tr> |
243 | 242 | "); |
244 | 243 | } |
245 | 244 | |
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' ) ) { |
248 | 248 | $wgOut->addHTML(" |
249 | 249 | <tr id='wpEnableEmailBan'> |
250 | 250 | <td> </td> |
251 | 251 | <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' )) . " |
255 | 255 | </td> |
256 | 256 | </tr> |
257 | 257 | "); |
258 | 258 | } |
259 | | - |
260 | 259 | $wgOut->addHTML(" |
261 | 260 | <tr> |
262 | 261 | <td style='padding-top: 1em'> </td> |
Index: trunk/phase3/includes/LogPage.php |
— | — | @@ -50,7 +50,7 @@ |
51 | 51 | function saveContent() { |
52 | 52 | if( wfReadOnly() ) return false; |
53 | 53 | |
54 | | - global $wgUser, $wgLogRestrictions; |
| 54 | + global $wgUser; |
55 | 55 | $fname = 'LogPage::saveContent'; |
56 | 56 | |
57 | 57 | $dbw = wfGetDB( DB_MASTER ); |
— | — | @@ -68,18 +68,20 @@ |
69 | 69 | 'log_comment' => $this->comment, |
70 | 70 | 'log_params' => $this->params |
71 | 71 | ); |
| 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 | + } |
72 | 78 | $dbw->insert( 'logging', $data, $fname ); |
73 | | - $newId = $dbw->insertId(); |
74 | 79 | |
75 | 80 | # 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 ); |
84 | 86 | } |
85 | 87 | return true; |
86 | 88 | } |
— | — | @@ -131,7 +133,7 @@ |
132 | 134 | */ |
133 | 135 | static function logHeader( $type ) { |
134 | 136 | global $wgLogHeaders; |
135 | | - return wfMsgHtml( $wgLogHeaders[$type] ); |
| 137 | + return wfMsg( $wgLogHeaders[$type] ); |
136 | 138 | } |
137 | 139 | |
138 | 140 | /** |
— | — | @@ -171,11 +173,6 @@ |
172 | 174 | $text = $wgContLang->ucfirst( $title->getText() ); |
173 | 175 | $titleLink = $skin->makeLinkObj( Title::makeTitle( NS_USER, $text ) ); |
174 | 176 | 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; |
180 | 177 | default: |
181 | 178 | $titleLink = $skin->makeLinkObj( $title ); |
182 | 179 | } |
— | — | @@ -202,7 +199,7 @@ |
203 | 200 | } |
204 | 201 | } else { |
205 | 202 | array_unshift( $params, $titleLink ); |
206 | | - if ( $key == 'block/block' || $key == 'oversight/block' ) { |
| 203 | + if ( $key == 'block/block' ) { |
207 | 204 | if ( $skin ) { |
208 | 205 | $params[1] = '<span title="' . htmlspecialchars( $params[1] ). '">' . $wgLang->translateBlockExpiry( $params[1] ) . '</span>'; |
209 | 206 | } else { |
Index: trunk/phase3/includes/SpecialRevisiondelete.php |
— | — | @@ -1,58 +1,38 @@ |
2 | 2 | <?php |
3 | 3 | |
4 | 4 | /** |
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. |
7 | 7 | * |
8 | | - * @addtogroup SpecialPage |
| 8 | + * To try this out, set up extra permissions something like: |
| 9 | + * $wgGroupPermissions['sysop']['deleterevision'] = true; |
| 10 | + * $wgGroupPermissions['bureaucrat']['hiderevision'] = true; |
9 | 11 | */ |
10 | 12 | |
11 | 13 | 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 | + |
23 | 19 | $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' ); |
26 | 23 | return; |
27 | 24 | } |
28 | | - # Only one target set at a time please! |
29 | | - $inputs = !empty($file) + !empty($oldid) + !empty($logid) + !empty($artimestamp) + |
30 | | - !empty($fileid) + !empty($image); |
31 | 25 | |
32 | | - if( $inputs > 1 || $inputs==0 ) { |
| 26 | + if( is_null( $oldid ) ) { |
33 | 27 | $wgOut->showErrorPage( 'revdelete-nooldid-title', 'revdelete-nooldid-text' ); |
34 | 28 | return; |
35 | 29 | } |
36 | | - # Either submit or create our form |
37 | | - $form = new RevisionDeleteForm( $page, $oldid, $logid, $artimestamp, $fileid, $image, $file ); |
| 30 | + |
| 31 | + $form = new RevisionDeleteForm( $wgRequest ); |
38 | 32 | if( $wgRequest->wasPosted() ) { |
39 | 33 | $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 ); |
46 | 36 | } |
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 | | - } |
57 | 37 | } |
58 | 38 | |
59 | 39 | /** |
— | — | @@ -62,410 +42,54 @@ |
63 | 43 | class RevisionDeleteForm { |
64 | 44 | /** |
65 | 45 | * @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 |
72 | 47 | */ |
73 | | - function __construct( $page, $oldids=null, $logids=null, $artimestamps=null, $fileids=null, $oldimages=null, $file=null ) { |
| 48 | + function __construct( $request ) { |
74 | 49 | global $wgUser; |
75 | | - |
76 | | - $this->page = $page; |
77 | | - $this->skin = $wgUser->getSkin(); |
78 | 50 | |
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(); |
115 | 57 | $this->checks = array( |
116 | | - $hide_content_name, |
| 58 | + array( 'revdelete-hide-text', 'wpHideText', Revision::DELETED_TEXT ), |
117 | 59 | array( 'revdelete-hide-comment', 'wpHideComment', Revision::DELETED_COMMENT ), |
118 | 60 | array( 'revdelete-hide-user', 'wpHideUser', Revision::DELETED_USER ), |
119 | 61 | array( 'revdelete-hide-restricted', 'wpHideRestricted', Revision::DELETED_RESTRICTED ) ); |
120 | 62 | } |
121 | 63 | |
122 | 64 | /** |
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 |
143 | 65 | * @param WebRequest $request |
144 | 66 | */ |
145 | | - function showRevs( $request ) { |
146 | | - global $wgOut, $wgUser, $action; |
| 67 | + function show( $request ) { |
| 68 | + global $wgOut, $wgUser; |
147 | 69 | |
148 | | - $UserAllowed = true; |
| 70 | + $wgOut->addWikiText( wfMsg( 'revdelete-selected', $this->page->getPrefixedText() ) ); |
149 | 71 | |
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; |
156 | 72 | $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 ) ) { |
443 | 76 | $wgOut->showErrorPage( 'revdelete-nooldid-title', 'revdelete-nooldid-text' ); |
444 | 77 | 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; |
452 | 78 | } |
453 | | - $wgOut->addHtml( $this->logLine( $logRows[$logid] ) ); |
454 | | - $bitfields |= $logRows[$logid]->log_deleted; |
| 79 | + $wgOut->addHtml( $this->historyLine( $rev ) ); |
| 80 | + $bitfields[] = $rev->mDeleted; // FIXME |
455 | 81 | } |
456 | 82 | $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' ) ); |
461 | 85 | |
462 | 86 | $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' ) ) ); |
465 | 89 | $hidden = array( |
466 | 90 | 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 ); |
470 | 94 | } |
471 | 95 | |
472 | 96 | $special = SpecialPage::getTitleFor( 'Revisiondelete' ); |
— | — | @@ -475,11 +99,10 @@ |
476 | 100 | null ) ); |
477 | 101 | |
478 | 102 | $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 |
480 | 103 | foreach( $this->checks as $item ) { |
481 | 104 | list( $message, $name, $field ) = $item; |
482 | 105 | $wgOut->addHtml( '<div>' . |
483 | | - wfCheckLabel( wfMsgHtml( $message), $name, $name, $bitfields & $field ) . |
| 106 | + wfCheckLabel( wfMsg( $message), $name, $name, $rev->isDeleted( $field ) ) . |
484 | 107 | '</div>' ); |
485 | 108 | } |
486 | 109 | $wgOut->addHtml( '</fieldset>' ); |
— | — | @@ -500,211 +123,32 @@ |
501 | 124 | function historyLine( $rev ) { |
502 | 125 | global $wgContLang; |
503 | 126 | $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×tamp=" . $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 | | - |
526 | 127 | 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>"; |
528 | 135 | } |
529 | 136 | |
530 | 137 | /** |
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 | | - /** |
658 | 138 | * @param WebRequest $request |
659 | 139 | */ |
660 | 140 | function submit( $request ) { |
661 | 141 | $bitfield = $this->extractBitfield( $request ); |
662 | 142 | $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 ); |
675 | 147 | } |
676 | 148 | } |
677 | 149 | |
678 | 150 | function success( $request ) { |
679 | 151 | 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' ); |
709 | 153 | } |
710 | 154 | |
711 | 155 | /** |
— | — | @@ -723,26 +167,10 @@ |
724 | 168 | return $bitfield; |
725 | 169 | } |
726 | 170 | |
727 | | - function save( $bitfield, $reason, $title ) { |
| 171 | + function save( $bitfield, $reason ) { |
728 | 172 | $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 | | - |
734 | 173 | $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 ); |
747 | 175 | } |
748 | 176 | } |
749 | 177 | |
— | — | @@ -752,510 +180,42 @@ |
753 | 181 | */ |
754 | 182 | class RevisionDeleter { |
755 | 183 | function __construct( $db ) { |
756 | | - $this->dbw = $db; |
| 184 | + $this->db = $db; |
757 | 185 | } |
758 | 186 | |
759 | 187 | /** |
760 | | - * @param $title, the page these events apply to |
761 | 188 | * @param array $items list of revision ID numbers |
762 | 189 | * @param int $bitfield new rev_deleted value |
763 | 190 | * @param string $comment Comment for log records |
764 | 191 | */ |
765 | | - function setRevVisibility( $title, $items, $bitfield, $comment ) { |
766 | | - global $wgOut; |
| 192 | + function setVisibility( $items, $bitfield, $comment ) { |
| 193 | + $pages = array(); |
767 | 194 | |
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 | | - } |
783 | 195 | // To work! |
784 | 196 | 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; |
791 | 200 | } |
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 ); |
924 | 203 | |
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]++; |
1126 | 208 | } else { |
1127 | | - $group = null; |
1128 | | - $key = null; |
1129 | | - $transaction = false; // Return an error and do nothing |
| 209 | + $pages[$pageid] = 1; |
1130 | 210 | } |
1131 | | - } else { |
1132 | | - wfDebug( __METHOD__." deleting already-missing '$oldpath'; moving on to database\n" ); |
1133 | | - $group = null; |
1134 | | - $key = ''; |
1135 | | - $transaction = new FSTransaction(); // empty |
1136 | 211 | } |
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 | | - } |
1144 | 212 | |
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 ); |
1168 | 218 | } |
1169 | 219 | |
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 | | - |
1260 | 220 | return true; |
1261 | 221 | } |
1262 | 222 | |
— | — | @@ -1265,87 +225,29 @@ |
1266 | 226 | * @param int $bitfield new rev_deleted bitfield value |
1267 | 227 | */ |
1268 | 228 | function updateRevision( $rev, $bitfield ) { |
1269 | | - $this->dbw->update( 'revision', |
| 229 | + $this->db->update( 'revision', |
1270 | 230 | array( 'rev_deleted' => $bitfield ), |
1271 | 231 | array( 'rev_id' => $rev->getId() ), |
1272 | 232 | 'RevisionDeleter::updateRevision' ); |
1273 | 233 | } |
1274 | 234 | |
1275 | 235 | /** |
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 | | - /** |
1324 | 236 | * Update the revision's recentchanges record if fields have been hidden |
1325 | 237 | * @param Revision $rev |
1326 | 238 | * @param int $bitfield new rev_deleted bitfield value |
1327 | 239 | */ |
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' ); |
1334 | 249 | } |
1335 | 250 | |
1336 | 251 | /** |
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 | | - /** |
1350 | 252 | * Touch the page's cache invalidation timestamp; this forces cached |
1351 | 253 | * history views to refresh, so any newly hidden or shown fields will |
1352 | 254 | * update properly. |
— | — | @@ -1353,39 +255,21 @@ |
1354 | 256 | */ |
1355 | 257 | function updatePage( $title ) { |
1356 | 258 | $title->invalidateCache(); |
1357 | | - $title->purgeSquid(); |
1358 | | - |
1359 | | - // Extensions that require referencing previous revisions may need this |
1360 | | - wfRunHooks( 'ArticleRevisionVisiblitySet', array( &$title ) ); |
1361 | 259 | } |
1362 | 260 | |
1363 | 261 | /** |
1364 | 262 | * Record a log entry on the action |
1365 | | - * @param Title $title, page where item was removed from |
| 263 | + * @param Title $title |
1366 | 264 | * @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 |
1369 | 266 | * @param string $comment |
1370 | | - * @param Title $target, the relevant page |
1371 | | - * @param string $param, URL param |
1372 | | - * @param Array $items |
1373 | 267 | */ |
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 ); |
1391 | 273 | } |
1392 | 274 | } |
| 275 | + |
| 276 | + |
Index: trunk/phase3/includes/EditPage.php |
— | — | @@ -982,13 +982,9 @@ |
983 | 983 | } |
984 | 984 | if ( isset( $this->mArticle ) && isset( $this->mArticle->mRevision ) ) { |
985 | 985 | // 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 ) ) { |
990 | 987 | $wgOut->addWikiText( wfMsg( 'rev-deleted-text-view' ) ); |
991 | 988 | } |
992 | | - |
993 | 989 | if( !$this->mArticle->mRevision->isCurrent() ) { |
994 | 990 | $this->mArticle->setOldSubtitle( $this->mArticle->mRevision->getId() ); |
995 | 991 | $wgOut->addWikiText( wfMsg( 'editingold' ) ); |
Index: trunk/phase3/includes/FileDeleteForm.php |
— | — | @@ -46,14 +46,8 @@ |
47 | 47 | return; |
48 | 48 | } |
49 | 49 | |
50 | | - # Use revision delete |
51 | | - # $this->oldimage = $wgRequest->getText( 'oldimage', false ); |
52 | | - |
53 | | - $this->oldimage = false; |
| 50 | + $this->oldimage = $wgRequest->getText( 'oldimage', false ); |
54 | 51 | $token = $wgRequest->getText( 'wpEditToken' ); |
55 | | - # Flag to hide all contents of the archived revisions |
56 | | - $suppress = $wgRequest->getVal( 'wpSuppress' ) && $wgUser->isAllowed('deleterevision'); |
57 | | - |
58 | 52 | if( $this->oldimage && !$this->isValidOldSpec() ) { |
59 | 53 | $wgOut->showUnexpectedValueError( 'oldimage', htmlspecialchars( $this->oldimage ) ); |
60 | 54 | return; |
— | — | @@ -71,7 +65,7 @@ |
72 | 66 | if( $wgRequest->wasPosted() && $wgUser->matchEditToken( $token, $this->oldimage ) ) { |
73 | 67 | $comment = $wgRequest->getText( 'wpReason' ); |
74 | 68 | if( $this->oldimage ) { |
75 | | - $status = $this->file->deleteOld( $this->oldimage, $comment, $suppress ); |
| 69 | + $status = $this->file->deleteOld( $this->oldimage, $comment ); |
76 | 70 | if( $status->ok ) { |
77 | 71 | // Need to do a log item |
78 | 72 | $log = new LogPage( 'delete' ); |
— | — | @@ -81,7 +75,7 @@ |
82 | 76 | $log->addEntry( 'delete', $this->title, $logComment ); |
83 | 77 | } |
84 | 78 | } else { |
85 | | - $status = $this->file->delete( $comment, $suppress ); |
| 79 | + $status = $this->file->delete( $comment ); |
86 | 80 | if( $status->ok ) { |
87 | 81 | // Need to delete the associated article |
88 | 82 | $article = new Article( $this->title ); |
Index: trunk/phase3/includes/Setup.php |
— | — | @@ -57,10 +57,8 @@ |
58 | 58 | if ( empty( $wgFileStore['deleted']['directory'] ) ) { |
59 | 59 | $wgFileStore['deleted']['directory'] = "{$wgUploadDirectory}/deleted"; |
60 | 60 | } |
61 | | -if ( empty( $wgFileStore['hidden']['directory'] ) ) { |
62 | | - $wgFileStore['hidden']['directory'] = "{$wgUploadDirectory}/hidden"; |
63 | | -} |
64 | 61 | |
| 62 | + |
65 | 63 | /** |
66 | 64 | * Initialise $wgLocalFileRepo from backwards-compatible settings |
67 | 65 | */ |
— | — | @@ -75,9 +73,7 @@ |
76 | 74 | 'transformVia404' => !$wgGenerateThumbnailOnParse, |
77 | 75 | 'initialCapital' => $wgCapitalLinks, |
78 | 76 | 'deletedDir' => $wgFileStore['deleted']['directory'], |
79 | | - 'deletedHashLevels' => $wgFileStore['deleted']['hash'], |
80 | | - 'hiddenDir' => $wgFileStore['hidden']['directory'], |
81 | | - 'hiddenHashLevels' => $wgFileStore['hidden']['hash'] |
| 77 | + 'deletedHashLevels' => $wgFileStore['deleted']['hash'] |
82 | 78 | ); |
83 | 79 | } |
84 | 80 | /** |
Index: trunk/phase3/includes/SpecialWatchlist.php |
— | — | @@ -161,8 +161,7 @@ |
162 | 162 | $andLatest=''; |
163 | 163 | $limitWatchlist = 'LIMIT ' . intval( $wgUser->getOption( 'wllimit' ) ); |
164 | 164 | } 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'; |
167 | 166 | $limitWatchlist = ''; |
168 | 167 | } |
169 | 168 | |
— | — | @@ -365,4 +364,4 @@ |
366 | 365 | $count = floor( $count / 2 ); |
367 | 366 | |
368 | 367 | return( $count ); |
369 | | -} |
| 368 | +} |
\ No newline at end of file |
Index: trunk/phase3/includes/ChangesList.php |
— | — | @@ -75,7 +75,7 @@ |
76 | 76 | : $nothing; |
77 | 77 | $f .= $bot ? '<span class="bot">' . $this->message['boteditletter'] . '</span>' : $nothing; |
78 | 78 | $f .= $patrolled ? '<span class="unpatrolled">!</span>' : $nothing; |
79 | | - return "<tt>$f</tt>"; |
| 79 | + return $f; |
80 | 80 | } |
81 | 81 | |
82 | 82 | /** |
— | — | @@ -101,32 +101,6 @@ |
102 | 102 | } |
103 | 103 | } |
104 | 104 | |
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 | | - } |
131 | 105 | |
132 | 106 | function insertMove( &$s, $rc ) { |
133 | 107 | # Diff |
— | — | @@ -162,12 +136,11 @@ |
163 | 137 | $s .= '(' . $this->skin->makeKnownLinkObj($title, $logname ) . ')'; |
164 | 138 | } |
165 | 139 | |
| 140 | + |
166 | 141 | function insertDiffHist(&$s, &$rc, $unpatrolled) { |
167 | 142 | # Diff link |
168 | | - if( !$this->userCan($rc,Revision::DELETED_TEXT) ) { |
| 143 | + if( $rc->mAttribs['rc_type'] == RC_NEW || $rc->mAttribs['rc_type'] == RC_LOG ) { |
169 | 144 | $diffLink = $this->message['diff']; |
170 | | - } else if( $rc->mAttribs['rc_type'] == RC_NEW || $rc->mAttribs['rc_type'] == RC_LOG ) { |
171 | | - $diffLink = $this->message['diff']; |
172 | 145 | } else { |
173 | 146 | $rcidparam = $unpatrolled |
174 | 147 | ? array( 'rcid' => $rc->mAttribs['rc_id'] ) |
— | — | @@ -197,12 +170,7 @@ |
198 | 171 | $params = ( $unpatrolled && $rc->mAttribs['rc_type'] == RC_NEW ) |
199 | 172 | ? 'rcid='.$rc->mAttribs['rc_id'] |
200 | 173 | : ''; |
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 ); |
207 | 175 | if( $watched ) |
208 | 176 | $articlelink = "<strong class=\"mw-watched\">{$articlelink}</strong>"; |
209 | 177 | global $wgContLang; |
— | — | @@ -219,38 +187,15 @@ |
220 | 188 | |
221 | 189 | /** Insert links to user page, user talk page and eventually a blocking link */ |
222 | 190 | 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'] ); |
229 | 193 | } |
230 | 194 | |
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 | | - |
245 | 195 | /** insert a formatted comment */ |
246 | 196 | function insertComment(&$s, &$rc) { |
247 | 197 | # Add comment |
248 | 198 | 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() ); |
255 | 200 | } |
256 | 201 | } |
257 | 202 | |
— | — | @@ -306,22 +251,18 @@ |
307 | 252 | |
308 | 253 | $s .= '<li>'; |
309 | 254 | |
310 | | - // Moved pages |
| 255 | + // moved pages |
311 | 256 | if( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) { |
312 | 257 | $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 ) { |
319 | 260 | list( $specialName, $specialSubpage ) = SpecialPage::resolveAliasWithSubpage( $rc_title ); |
320 | 261 | if ( $specialName == 'Log' ) { |
321 | 262 | $this->insertLog( $s, $rc->getTitle(), $specialSubpage ); |
322 | 263 | } else { |
323 | 264 | wfDebug( "Unexpected special page in recentchanges\n" ); |
324 | 265 | } |
325 | | - // Log entries |
| 266 | + // all other stuff |
326 | 267 | } else { |
327 | 268 | wfProfileIn($fname.'-page'); |
328 | 269 | |
— | — | @@ -343,16 +284,10 @@ |
344 | 285 | } |
345 | 286 | |
346 | 287 | $this->insertUserRelatedLinks($s,$rc); |
347 | | - $this->insertAction($s, $rc); |
348 | 288 | $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 | | - } |
356 | 289 | |
| 290 | + $s .= rtrim(' ' . $this->numberofWatchingusers($rc->numberofWatchingusers)); |
| 291 | + |
357 | 292 | $s .= "</li>\n"; |
358 | 293 | |
359 | 294 | wfProfileOut( $fname.'-rest' ); |
— | — | @@ -399,14 +334,12 @@ |
400 | 335 | $rc->unpatrolled = false; |
401 | 336 | } |
402 | 337 | |
403 | | - $showrev=true; |
404 | 338 | # Make article link |
405 | 339 | if( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) { |
406 | 340 | $msg = ( $rc_type == RC_MOVE ) ? "1movedto2" : "1movedto2_redir"; |
407 | 341 | $clink = wfMsg( $msg, $this->skin->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ), |
408 | 342 | $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 ) { |
411 | 344 | list( $specialName, $logtype ) = SpecialPage::resolveAliasWithSubpage( $rc_title ); |
412 | 345 | if ( $specialName == 'Log' ) { |
413 | 346 | # Log updates, etc |
— | — | @@ -416,16 +349,7 @@ |
417 | 350 | wfDebug( "Unexpected special page in recentchanges\n" ); |
418 | 351 | $clink = ''; |
419 | 352 | } |
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 ) { |
430 | 354 | # Unpatrolled new page, give rc_id in query |
431 | 355 | $clink = $this->skin->makeKnownLinkObj( $rc->getTitle(), '', "rcid={$rc_id}" ); |
432 | 356 | } else { |
— | — | @@ -448,10 +372,7 @@ |
449 | 373 | $querydiff = $curIdEq."&diff=$rc_this_oldid&oldid=$rc_last_oldid$rcIdQuery"; |
450 | 374 | $aprops = ' tabindex="'.$baseRC->counter.'"'; |
451 | 375 | $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 ) { |
456 | 377 | if( $rc_type != RC_NEW ) { |
457 | 378 | $curLink = $this->message['cur']; |
458 | 379 | } |
— | — | @@ -461,27 +382,21 @@ |
462 | 383 | } |
463 | 384 | |
464 | 385 | # 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 ) { |
468 | 387 | $lastLink = $this->message['last']; |
469 | 388 | } else { |
470 | 389 | $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 ); |
472 | 391 | } |
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 | | - } |
481 | 392 | |
| 393 | + $rc->userlink = $this->skin->userLink( $rc_user, $rc_user_text ); |
| 394 | + |
482 | 395 | $rc->lastlink = $lastLink; |
483 | 396 | $rc->curlink = $curLink; |
484 | 397 | $rc->difflink = $diffLink; |
485 | 398 | |
| 399 | + $rc->usertalklink = $this->skin->userToolLinks( $rc_user, $rc_user_text ); |
| 400 | + |
486 | 401 | # Put accumulated information into the cache, for later display |
487 | 402 | # Page moves go on their own line |
488 | 403 | $title = $rc->getTitle(); |
— | — | @@ -503,11 +418,10 @@ |
504 | 419 | */ |
505 | 420 | function recentChangesBlockGroup( $block ) { |
506 | 421 | global $wgLang, $wgContLang, $wgRCShowChangedSize; |
507 | | - $r = '<table cellpadding="0" cellspacing="0"><tr>'; |
| 422 | + $r = ''; |
508 | 423 | |
509 | 424 | # Collate list of users |
510 | 425 | $isnew = false; |
511 | | - $namehidden = true; |
512 | 426 | $unpatrolled = false; |
513 | 427 | $userlinks = array(); |
514 | 428 | foreach( $block as $rcObj ) { |
— | — | @@ -515,11 +429,6 @@ |
516 | 430 | if( $rcObj->mAttribs['rc_new'] ) { |
517 | 431 | $isnew = true; |
518 | 432 | } |
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 | | - } |
524 | 433 | $u = $rcObj->userlink; |
525 | 434 | if( !isset( $userlinks[$u] ) ) { |
526 | 435 | $userlinks[$u] = 0; |
— | — | @@ -553,25 +462,24 @@ |
554 | 463 | $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')"; |
555 | 464 | $tl = '<span id="'.$rcm.'"><a href="'.$toggleLink.'">' . $this->sideArrow() . '</a></span>'; |
556 | 465 | $tl .= '<span id="'.$rcl.'" style="display:none"><a href="'.$toggleLink.'">' . $this->downArrow() . '</a></span>'; |
557 | | - $r .= '<td valign="top">'.$tl; |
| 466 | + $r .= $tl; |
558 | 467 | |
559 | 468 | # Main line |
560 | | - $r .= ' '.$this->recentChangesFlags( $isnew, false, $unpatrolled, ' ', $bot ); |
| 469 | + $r .= '<tt>'; |
| 470 | + $r .= $this->recentChangesFlags( $isnew, false, $unpatrolled, ' ', $bot ); |
561 | 471 | |
562 | 472 | # Timestamp |
563 | | - $r .= ' '.$block[0]->timestamp.' </td><td>'; |
| 473 | + $r .= ' '.$block[0]->timestamp.' </tt>'; |
564 | 474 | |
565 | 475 | # 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 ); |
570 | 477 | $r .= $wgContLang->getDirMark(); |
571 | 478 | |
572 | 479 | $curIdEq = 'curid=' . $block[0]->mAttribs['rc_cur_id']; |
573 | 480 | $currentRevision = $block[0]->mAttribs['rc_this_oldid']; |
574 | 481 | if( $block[0]->mAttribs['rc_type'] != RC_LOG ) { |
575 | 482 | # Changes |
| 483 | + |
576 | 484 | $n = count($block); |
577 | 485 | static $nchanges = array(); |
578 | 486 | if ( !isset( $nchanges[$n] ) ) { |
— | — | @@ -581,25 +489,25 @@ |
582 | 490 | |
583 | 491 | $r .= ' ('; |
584 | 492 | |
585 | | - if( !ChangesList::userCan($rcObj,Revision::DELETED_TEXT) ) { |
586 | | - $r .= $nchanges[$n]; |
587 | | - } else if( $isnew ) { |
| 493 | + if( $isnew ) { |
588 | 494 | $r .= $nchanges[$n]; |
589 | 495 | } else { |
590 | 496 | $r .= $this->skin->makeKnownLinkObj( $block[0]->getTitle(), |
591 | 497 | $nchanges[$n], $curIdEq."&diff=$currentRevision&oldid=$oldid" ); |
592 | 498 | } |
593 | 499 | |
| 500 | + $r .= ') . . '; |
| 501 | + |
594 | 502 | if( $wgRCShowChangedSize ) { |
595 | 503 | # Character difference |
596 | 504 | $chardiff = $rcObj->getCharacterDifference( $block[ count( $block ) - 1 ]->mAttribs['rc_old_len'], |
597 | 505 | $block[0]->mAttribs['rc_new_len'] ); |
598 | 506 | if( $chardiff == '' ) { |
599 | | - $r .= ') '; |
| 507 | + $r .= ' ('; |
600 | 508 | } else { |
601 | 509 | $r .= ' ' . $chardiff. ' . . '; |
602 | 510 | } |
603 | | - } |
| 511 | + } |
604 | 512 | |
605 | 513 | # History |
606 | 514 | $r .= '(' . $this->skin->makeKnownLinkObj( $block[0]->getTitle(), |
— | — | @@ -608,70 +516,51 @@ |
609 | 517 | } |
610 | 518 | |
611 | 519 | $r .= $users; |
612 | | - $r .=$this->numberofWatchingusers($block[0]->numberofWatchingusers); |
613 | | - |
614 | | - $r .= "</td></tr></table>\n"; |
615 | 520 | |
| 521 | + $r .= $this->numberofWatchingusers($block[0]->numberofWatchingusers); |
| 522 | + $r .= "<br />\n"; |
| 523 | + |
616 | 524 | # 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">'; |
618 | 526 | foreach( $block as $rcObj ) { |
619 | 527 | # Get rc_xxxx variables |
620 | 528 | // FIXME: Would be good to replace this extract() call with something that explicitly initializes local variables. |
621 | 529 | extract( $rcObj->mAttribs ); |
622 | 530 | |
623 | | - #$r .= '<tr><td valign="top">'.$this->spacerArrow(); |
624 | | - $r .= '<tr><td valign="top">'.$this->spacerIndent(); |
625 | | - $r .= ' '; |
| 531 | + $r .= $this->spacerArrow(); |
| 532 | + $r .= '<tt> '; |
626 | 533 | $r .= $this->recentChangesFlags( $rc_new, $rc_minor, $rcObj->unpatrolled, ' ', $rc_bot ); |
627 | | - $r .= ' </td><td valign="top">'; |
| 534 | + $r .= ' </tt>'; |
628 | 535 | |
629 | 536 | $o = ''; |
630 | 537 | if( $rc_this_oldid != 0 ) { |
631 | 538 | $o = 'oldid='.$rc_this_oldid; |
632 | 539 | } |
633 | | - # Revision link |
634 | 540 | 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; |
638 | 542 | } else { |
639 | 543 | $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> '; |
642 | 544 | } |
| 545 | + $link = '<tt>'.$link.'</tt>'; |
| 546 | + |
643 | 547 | $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 .= ') . . '; |
657 | 553 | |
658 | 554 | # Character diff |
659 | 555 | if( $wgRCShowChangedSize ) { |
660 | 556 | $r .= ( $rcObj->getCharacterDifference() == '' ? '' : $rcObj->getCharacterDifference() . ' . . ' ) ; |
661 | 557 | } |
662 | | - # User links |
| 558 | + |
663 | 559 | $r .= $rcObj->userlink; |
664 | 560 | $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"; |
674 | 563 | } |
675 | | - $r .= "</table></div>\n"; |
| 564 | + $r .= "</div>\n"; |
676 | 565 | |
677 | 566 | $this->rcCacheIndex++; |
678 | 567 | return $r; |
— | — | @@ -728,23 +617,8 @@ |
729 | 618 | * @access private |
730 | 619 | */ |
731 | 620 | function spacerArrow() { |
732 | | - //FIXME: problems with FF 1.5x |
733 | 621 | return $this->arrow( '', ' ' ); |
734 | 622 | } |
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 ' '; |
748 | | - } |
749 | 623 | |
750 | 624 | /** |
751 | 625 | * Enhanced RC ungrouped line. |
— | — | @@ -758,64 +632,46 @@ |
759 | 633 | extract( $rcObj->mAttribs ); |
760 | 634 | $curIdEq = 'curid='.$rc_cur_id; |
761 | 635 | |
762 | | - $r = '<table cellspacing="0" cellpadding="0"><tr><td>'; |
| 636 | + $r = ''; |
763 | 637 | |
764 | | - # spacerArrow() causes issues in FF |
765 | | - $r .= $this->spacerColumn(); |
766 | | - $r .= '<td valign="top">'; |
767 | | - |
| 638 | + # Spacer image |
| 639 | + $r .= $this->spacerArrow(); |
| 640 | + |
768 | 641 | # Flag and Timestamp |
| 642 | + $r .= '<tt>'; |
| 643 | + |
769 | 644 | if( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) { |
770 | | - $r .= ' '; |
| 645 | + $r .= ' '; |
771 | 646 | } else { |
772 | | - $r .= ' '.$this->recentChangesFlags( $rc_type == RC_NEW, $rc_minor, $rcObj->unpatrolled, ' ', $rc_bot ); |
| 647 | + $r .= $this->recentChangesFlags( $rc_type == RC_NEW, $rc_minor, $rcObj->unpatrolled, ' ', $rc_bot ); |
773 | 648 | } |
774 | | - $r .= ' '.$rcObj->timestamp.' </td><td>'; |
775 | | - |
| 649 | + $r .= ' '.$rcObj->timestamp.' </tt>'; |
| 650 | + |
776 | 651 | # 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 | + |
793 | 660 | # Character diff |
794 | 661 | if( $wgRCShowChangedSize ) { |
795 | 662 | $r .= ( $rcObj->getCharacterDifference() == '' ? '' : ' ' . $rcObj->getCharacterDifference() . ' . . ' ) ; |
796 | 663 | } |
797 | 664 | |
798 | 665 | # User/talk |
799 | | - $r .= ' '.$rcObj->userlink . $rcObj->usertalklink; |
| 666 | + $r .= $rcObj->userlink . $rcObj->usertalklink; |
800 | 667 | |
801 | 668 | # Comment |
802 | 669 | 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() ); |
815 | 671 | } |
816 | 672 | |
817 | 673 | $r .= $this->numberofWatchingusers($rcObj->numberofWatchingusers); |
818 | 674 | |
819 | | - $r .= "</td></tr></table>\n"; |
| 675 | + $r .= "<br />\n"; |
820 | 676 | return $r; |
821 | 677 | } |
822 | 678 | |
Index: trunk/phase3/includes/Article.php |
— | — | @@ -390,7 +390,6 @@ |
391 | 391 | // We should instead work with the Revision object when we need it... |
392 | 392 | $this->mContent = $revision->userCan( Revision::DELETED_TEXT ) ? $revision->getRawText() : ""; |
393 | 393 | //$this->mContent = $revision->getText(); |
394 | | - $this->mContent = $revision->revText(); // Loads if user is allowed |
395 | 394 | |
396 | 395 | $this->mUser = $revision->getUser(); |
397 | 396 | $this->mUserText = $revision->getUserText(); |
— | — | @@ -1070,6 +1069,7 @@ |
1071 | 1070 | $result = $dbw->affectedRows() != 0; |
1072 | 1071 | |
1073 | 1072 | if ($result) { |
| 1073 | + // FIXME: Should the result from updateRedirectOn() be returned instead? |
1074 | 1074 | $this->updateRedirectOn( $dbw, $rt, $lastRevIsRedirect ); |
1075 | 1075 | } |
1076 | 1076 | |
— | — | @@ -1494,7 +1494,6 @@ |
1495 | 1495 | * |
1496 | 1496 | * @param boolean $noRedir Add redirect=no |
1497 | 1497 | * @param string $sectionAnchor section to redirect to, including "#" |
1498 | | - * @param string $extraq, extra query params |
1499 | 1498 | */ |
1500 | 1499 | function doRedirect( $noRedir = false, $sectionAnchor = '', $extraq = '' ) { |
1501 | 1500 | global $wgOut; |
— | — | @@ -1690,7 +1689,7 @@ |
1691 | 1690 | * @return bool true on success |
1692 | 1691 | */ |
1693 | 1692 | function updateRestrictions( $limit = array(), $reason = '', $cascade = 0, $expiry = null ) { |
1694 | | - global $wgUser, $wgRestrictionTypes, $wgContLang, $wgGroupPermissions; |
| 1693 | + global $wgUser, $wgRestrictionTypes, $wgContLang; |
1695 | 1694 | |
1696 | 1695 | $id = $this->mTitle->getArticleID(); |
1697 | 1696 | if( !$wgUser->isAllowed( 'protect' ) || wfReadOnly() || $id == 0 ) { |
— | — | @@ -1720,6 +1719,7 @@ |
1721 | 1720 | |
1722 | 1721 | # If nothing's changed, do nothing |
1723 | 1722 | if( $changed ) { |
| 1723 | + global $wgGroupPermissions; |
1724 | 1724 | if( wfRunHooks( 'ArticleProtect', array( &$this, &$wgUser, $limit, $reason ) ) ) { |
1725 | 1725 | |
1726 | 1726 | $dbw = wfGetDB( DB_MASTER ); |
— | — | @@ -1832,8 +1832,6 @@ |
1833 | 1833 | $confirm = $wgRequest->wasPosted() && |
1834 | 1834 | $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ); |
1835 | 1835 | $reason = $wgRequest->getText( 'wpReason' ); |
1836 | | - # Flag to hide all contents of the archived revisions |
1837 | | - $suppress = $wgRequest->getVal( 'wpSuppress' ) && $wgUser->isAllowed('deleterevision'); |
1838 | 1836 | |
1839 | 1837 | # This code desperately needs to be totally rewritten |
1840 | 1838 | |
— | — | @@ -1858,7 +1856,7 @@ |
1859 | 1857 | } |
1860 | 1858 | |
1861 | 1859 | if( $confirm ) { |
1862 | | - $this->doDelete( $reason, $suppress ); |
| 1860 | + $this->doDelete( $reason ); |
1863 | 1861 | if( $wgRequest->getCheck( 'wpWatch' ) ) { |
1864 | 1862 | $this->doWatch(); |
1865 | 1863 | } elseif( $this->mTitle->userIsWatching() ) { |
— | — | @@ -2004,14 +2002,7 @@ |
2005 | 2003 | $delcom = htmlspecialchars( wfMsg( 'deletecomment' ) ); |
2006 | 2004 | $token = htmlspecialchars( $wgUser->editToken() ); |
2007 | 2005 | $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> </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 | + |
2016 | 2007 | $wgOut->addHTML( " |
2017 | 2008 | <form id='deleteconfirm' method='post' action=\"{$formaction}\"> |
2018 | 2009 | <table border='0'> |
— | — | @@ -2023,7 +2014,6 @@ |
2024 | 2015 | <input type='text' size='60' name='wpReason' id='wpReason' value=\"" . htmlspecialchars( $reason ) . "\" tabindex=\"1\" /> |
2025 | 2016 | </td> |
2026 | 2017 | </tr> |
2027 | | - $supress |
2028 | 2018 | <tr> |
2029 | 2019 | <td> </td> |
2030 | 2020 | <td>$watch</td> |
— | — | @@ -2061,12 +2051,12 @@ |
2062 | 2052 | /** |
2063 | 2053 | * Perform a deletion and output success or failure messages |
2064 | 2054 | */ |
2065 | | - function doDelete( $reason, $suppress = false ) { |
| 2055 | + function doDelete( $reason ) { |
2066 | 2056 | global $wgOut, $wgUser; |
2067 | 2057 | wfDebug( __METHOD__."\n" ); |
2068 | 2058 | |
2069 | 2059 | if (wfRunHooks('ArticleDelete', array(&$this, &$wgUser, &$reason))) { |
2070 | | - if ( $this->doDeleteArticle( $reason, $suppress ) ) { |
| 2060 | + if ( $this->doDeleteArticle( $reason ) ) { |
2071 | 2061 | $deleted = wfEscapeWikiText( $this->mTitle->getPrefixedText() ); |
2072 | 2062 | |
2073 | 2063 | $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) ); |
— | — | @@ -2079,7 +2069,7 @@ |
2080 | 2070 | $wgOut->returnToMain( false ); |
2081 | 2071 | wfRunHooks('ArticleDeleteComplete', array(&$this, &$wgUser, $reason)); |
2082 | 2072 | } else { |
2083 | | - $wgOut->showFatalError( wfMsg( 'cannotdelete' ).'<br/>'.wfMsg('cannotdelete-merge') ); |
| 2073 | + $wgOut->showFatalError( wfMsg( 'cannotdelete' ) ); |
2084 | 2074 | } |
2085 | 2075 | } |
2086 | 2076 | } |
— | — | @@ -2089,7 +2079,7 @@ |
2090 | 2080 | * Deletes the article with database consistency, writes logs, purges caches |
2091 | 2081 | * Returns success |
2092 | 2082 | */ |
2093 | | - function doDeleteArticle( $reason, $suppress = false ) { |
| 2083 | + function doDeleteArticle( $reason ) { |
2094 | 2084 | global $wgUseSquid, $wgDeferredUpdateList; |
2095 | 2085 | global $wgUseTrackbacks; |
2096 | 2086 | |
— | — | @@ -2103,30 +2093,10 @@ |
2104 | 2094 | if ( $t == '' || $id == 0 ) { |
2105 | 2095 | return false; |
2106 | 2096 | } |
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; |
2115 | 2097 | |
2116 | 2098 | $u = new SiteStatsUpdate( 0, 1, -(int)$this->isCountable( $this->getContent() ), -1 ); |
2117 | 2099 | array_push( $wgDeferredUpdateList, $u ); |
2118 | 2100 | |
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 | | - |
2131 | 2101 | // For now, shunt the revision data into the archive table. |
2132 | 2102 | // Text is *not* removed from the text table; bulk storage |
2133 | 2103 | // is left intact to avoid breaking block-compression or |
— | — | @@ -2152,7 +2122,6 @@ |
2153 | 2123 | 'ar_flags' => '\'\'', // MySQL's "strict mode"... |
2154 | 2124 | 'ar_len' => 'rev_len', |
2155 | 2125 | 'ar_page_id' => 'page_id', |
2156 | | - 'ar_deleted' => $bitfield |
2157 | 2126 | ), array( |
2158 | 2127 | 'page_id' => $id, |
2159 | 2128 | 'page_id = rev_page' |
— | — | @@ -2193,9 +2162,8 @@ |
2194 | 2163 | # Clear caches |
2195 | 2164 | Article::onArticleDelete( $this->mTitle ); |
2196 | 2165 | |
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' ); |
2200 | 2168 | $log->addEntry( 'delete', $this->mTitle, $reason ); |
2201 | 2169 | |
2202 | 2170 | # Clear the cached article id so the interface doesn't act like we exist |
— | — | @@ -2294,13 +2262,8 @@ |
2295 | 2263 | ); |
2296 | 2264 | } |
2297 | 2265 | |
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 | | - } |
2304 | 2266 | # Get the edit summary |
| 2267 | + $target = Revision::newFromId( $s->rev_id ); |
2305 | 2268 | if( empty( $summary ) ) |
2306 | 2269 | $summary = wfMsgForContent( 'revertpage', $target->getUserText(), $from ); |
2307 | 2270 | |
— | — | @@ -2561,28 +2524,8 @@ |
2562 | 2525 | ? wfMsg( 'diff' ) |
2563 | 2526 | : $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'diff' ), 'diff=next&oldid='.$oldid ); |
2564 | 2527 | |
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() ); |
2587 | 2530 | |
2588 | 2531 | $m = wfMsg( 'revision-info-current' ); |
2589 | 2532 | $infomsg = $current && !wfEmptyMsg( 'revision-info-current', $m ) && $m != '-' |
— | — | @@ -2590,8 +2533,7 @@ |
2591 | 2534 | : 'revision-info'; |
2592 | 2535 | |
2593 | 2536 | $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"; |
2596 | 2538 | $wgOut->setSubtitle( $r ); |
2597 | 2539 | } |
2598 | 2540 | |
Index: trunk/phase3/includes/Revision.php |
— | — | @@ -794,7 +794,7 @@ |
795 | 795 | * @param bool $minor |
796 | 796 | * @return Revision |
797 | 797 | */ |
798 | | - static function newNullRevision( &$dbw, $pageId, $summary, $minor ) { |
| 798 | + function newNullRevision( &$dbw, $pageId, $summary, $minor ) { |
799 | 799 | $fname = 'Revision::newNullRevision'; |
800 | 800 | wfProfileIn( $fname ); |
801 | 801 | |
Index: trunk/phase3/includes/SpecialSpecialpages.php |
— | — | @@ -16,13 +16,10 @@ |
17 | 17 | $sk = $wgUser->getSkin(); |
18 | 18 | |
19 | 19 | /** Pages available to all */ |
20 | | - wfSpecialSpecialpages_gen( SpecialPage::getRegularPages(), 'spheading', $sk, false ); |
| 20 | + wfSpecialSpecialpages_gen( SpecialPage::getRegularPages(), 'spheading', $sk ); |
21 | 21 | |
22 | 22 | /** 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 ); |
27 | 24 | } |
28 | 25 | |
29 | 26 | /** |
— | — | @@ -30,10 +27,9 @@ |
31 | 28 | * @param $pages the list of pages |
32 | 29 | * @param $heading header to be used |
33 | 30 | * @param $sk skin object ??? |
34 | | - * @param $islog, is this for a list of log types? |
35 | 31 | */ |
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; |
38 | 34 | |
39 | 35 | if( count( $pages ) == 0 ) { |
40 | 36 | # Yeah, that was pointless. Thanks for coming. |
— | — | @@ -42,13 +38,9 @@ |
43 | 39 | |
44 | 40 | /** Put them into a sortable array */ |
45 | 41 | $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(); |
53 | 45 | } |
54 | 46 | } |
55 | 47 | |
Index: trunk/phase3/includes/DifferenceEngine.php |
— | — | @@ -48,7 +48,7 @@ |
49 | 49 | # Show diff between revision $old and the previous one. |
50 | 50 | # Get previous one from DB. |
51 | 51 | # |
52 | | - $this->mNewid = intval($old); |
| 52 | + $this->mNewid = intval($old); |
53 | 53 | |
54 | 54 | $this->mOldid = $this->mTitle->getPreviousRevisionID( $this->mNewid ); |
55 | 55 | |
— | — | @@ -64,13 +64,6 @@ |
65 | 65 | $this->mNewid = 0; |
66 | 66 | } |
67 | 67 | |
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); |
75 | 68 | } else { |
76 | 69 | $this->mOldid = intval($old); |
77 | 70 | $this->mNewid = intval($new); |
— | — | @@ -227,49 +220,14 @@ |
228 | 221 | $newminor = wfElement( 'span', array( 'class' => 'minor' ), |
229 | 222 | wfMsg( 'minoreditletter') ) . ' '; |
230 | 223 | } |
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 = " <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 = " <tt>(<small>$rdel</small>)</tt> "; |
265 | | - } |
266 | 224 | |
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>" . |
274 | 232 | '<div id="mw-diff-ntitle4">' . $nextlink . $patrol . '</div>'; |
275 | 233 | |
276 | 234 | $this->showDiff( $oldHeader, $newHeader ); |
— | — | @@ -290,10 +248,8 @@ |
291 | 249 | |
292 | 250 | $wgOut->addHTML( "<hr /><h2>{$this->mPagetitle}</h2>\n" ); |
293 | 251 | #add deleted rev tag if needed |
294 | | - if( !$this->mNewRev->userCan(Revision::DELETED_TEXT) ) { |
| 252 | + if ( !$this->mNewRev->userCan(Revision::DELETED_TEXT) ) { |
295 | 253 | $wgOut->addWikiText( wfMsg( 'rev-deleted-text-permission' ) ); |
296 | | - } else if( $this->mNewRev->isDeleted(Revision::DELETED_TEXT) ) { |
297 | | - $wgOut->addWikiText( wfMsg( 'rev-deleted-text-view' ) ); |
298 | 254 | } |
299 | 255 | |
300 | 256 | if( !$this->mNewRev->isCurrent() ) { |
— | — | @@ -438,25 +394,20 @@ |
439 | 395 | } // don't try to load but save the result |
440 | 396 | } |
441 | 397 | |
442 | | - // Loadtext is permission safe, this just clears out the diff |
| 398 | + #loadtext is permission safe, this just clears out the diff |
443 | 399 | if ( !$this->loadText() ) { |
444 | 400 | wfProfileOut( $fname ); |
445 | 401 | return false; |
446 | 402 | } else if ( $this->mOldRev && !$this->mOldRev->userCan(Revision::DELETED_TEXT) ) { |
447 | | - return ''; |
| 403 | + return ''; |
448 | 404 | } else if ( $this->mNewRev && !$this->mNewRev->userCan(Revision::DELETED_TEXT) ) { |
449 | | - return ''; |
| 405 | + return ''; |
450 | 406 | } |
451 | 407 | |
452 | 408 | $difftext = $this->generateDiffBody( $this->mOldtext, $this->mNewtext ); |
453 | 409 | |
454 | 410 | // 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 ) { |
461 | 412 | wfIncrStats( 'diff_cache_miss' ); |
462 | 413 | $wgMemc->set( $key, $difftext, 7*86400 ); |
463 | 414 | } else { |
— | — | @@ -588,9 +539,15 @@ |
589 | 540 | /** |
590 | 541 | * Add the header to a diff body |
591 | 542 | */ |
592 | | - static function addHeader( $diff, $otitle, $ntitle, $multi = '' ) { |
| 543 | + function addHeader( $diff, $otitle, $ntitle, $multi = '' ) { |
593 | 544 | 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 | + } |
595 | 552 | $header = " |
596 | 553 | <table class='diff'> |
597 | 554 | <col class='diff-marker' /> |
— | — | @@ -643,10 +600,10 @@ |
644 | 601 | : Revision::newFromTitle( $this->mTitle ); |
645 | 602 | if( !$this->mNewRev instanceof Revision ) |
646 | 603 | return false; |
647 | | - |
| 604 | + |
648 | 605 | // Update the new revision ID in case it was 0 (makes life easier doing UI stuff) |
649 | 606 | $this->mNewid = $this->mNewRev->getId(); |
650 | | - |
| 607 | + |
651 | 608 | // Set assorted variables |
652 | 609 | $timestamp = $wgLang->timeanddate( $this->mNewRev->getTimestamp(), true ); |
653 | 610 | $this->mNewPage = $this->mNewRev->getTitle(); |
— | — | @@ -666,11 +623,6 @@ |
667 | 624 | $this->mNewtitle = "<a href='$newLink'>{$this->mPagetitle}</a>" |
668 | 625 | . " (<a href='$newEdit'>" . htmlspecialchars( wfMsg( 'editold' ) ) . "</a>)"; |
669 | 626 | } |
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 | | - } |
675 | 627 | |
676 | 628 | // Load the old revision object |
677 | 629 | $this->mOldRev = false; |
— | — | @@ -698,20 +650,12 @@ |
699 | 651 | $t = $wgLang->timeanddate( $this->mOldRev->getTimestamp(), true ); |
700 | 652 | $oldLink = $this->mOldPage->escapeLocalUrl( 'oldid=' . $this->mOldid ); |
701 | 653 | $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>)"; |
703 | 656 | |
704 | | - $this->mOldtitle = "<a href='$oldLink'>{$this->mOldPagetitle}</a>" |
705 | | - . "(<a href='$oldEdit'>" . htmlspecialchars( wfMsg( 'editold' ) ) . "</a>)"; |
706 | 657 | // Add an "undo" link |
707 | 658 | $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>)"; |
716 | 660 | } |
717 | 661 | |
718 | 662 | return true; |
— | — | @@ -732,6 +676,7 @@ |
733 | 677 | return false; |
734 | 678 | } |
735 | 679 | if ( $this->mOldRev ) { |
| 680 | + // FIXME: permission tests |
736 | 681 | $this->mOldtext = $this->mOldRev->revText(); |
737 | 682 | if ( $this->mOldtext === false ) { |
738 | 683 | return false; |
Index: trunk/phase3/maintenance/rebuildrecentchanges.inc |
— | — | @@ -11,6 +11,7 @@ |
12 | 12 | { |
13 | 13 | $fname = 'rebuildRecentChangesTablePass1'; |
14 | 14 | $dbw = wfGetDB( DB_MASTER ); |
| 15 | + extract( $dbw->tableNames( 'recentchanges', 'cur', 'old' ) ); |
15 | 16 | |
16 | 17 | $dbw->delete( 'recentchanges', '*' ); |
17 | 18 | |
— | — | @@ -34,7 +35,6 @@ |
35 | 36 | 'rc_this_oldid' => 'rev_id', |
36 | 37 | 'rc_last_oldid' => 0, // is this ok? |
37 | 38 | 'rc_type' => $dbw->conditional( 'page_is_new != 0', RC_NEW, RC_EDIT ), |
38 | | - 'rc_deleted' => 'rev_deleted' |
39 | 39 | ), array( |
40 | 40 | 'rev_timestamp > ' . $dbw->addQuotes( $dbw->timestamp( $cutoff ) ), |
41 | 41 | 'rev_page=page_id' |
— | — | @@ -99,70 +99,6 @@ |
100 | 100 | |
101 | 101 | function rebuildRecentChangesTablePass3() |
102 | 102 | { |
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 | | -{ |
167 | 103 | global $wgGroupPermissions, $wgUseRCPatrol; |
168 | 104 | |
169 | 105 | $dbw = wfGetDB( DB_MASTER ); |
Index: trunk/phase3/maintenance/rebuildrecentchanges.php |
— | — | @@ -17,8 +17,7 @@ |
18 | 18 | |
19 | 19 | rebuildRecentChangesTablePass1(); |
20 | 20 | rebuildRecentChangesTablePass2(); |
21 | | -rebuildRecentChangesTablePass3(); // logs entries |
22 | | -rebuildRecentChangesTablePass4(); // flag bot edits |
| 21 | +rebuildRecentChangesTablePass3(); // flag bot edits |
23 | 22 | |
24 | 23 | print "Done.\n"; |
25 | 24 | exit(); |