Localisation updates for core messages from Betawiki (2008-03-14 18:02 CET)
[lhc/web/wiklou.git] / includes / SpecialRevisiondelete.php
1 <?php
2
3 /**
4 * Not quite ready for production use yet; need to fix up the restricted mode,
5 * and provide for preservation across delete/undelete of the page.
6 *
7 * To try this out, set up extra permissions something like:
8 * $wgGroupPermissions['sysop']['deleterevision'] = true;
9 * $wgGroupPermissions['bureaucrat']['hiderevision'] = true;
10 */
11
12 function wfSpecialRevisiondelete( $par = null ) {
13 global $wgOut, $wgRequest;
14
15 $target = $wgRequest->getVal( 'target' );
16 $oldid = $wgRequest->getIntArray( 'oldid' );
17
18 $page = Title::newFromUrl( $target );
19
20 if( is_null( $page ) ) {
21 $wgOut->showErrorPage( 'notargettitle', 'notargettext' );
22 return;
23 }
24
25 if( is_null( $oldid ) ) {
26 $wgOut->showErrorPage( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
27 return;
28 }
29
30 $form = new RevisionDeleteForm( $wgRequest );
31 if( $wgRequest->wasPosted() ) {
32 $form->submit( $wgRequest );
33 } else {
34 $form->show( $wgRequest );
35 }
36 }
37
38 /**
39 * Implements the GUI for Revision Deletion.
40 * @addtogroup SpecialPage
41 */
42 class RevisionDeleteForm {
43 /**
44 * @param WebRequest $request
45 */
46 function __construct( $request ) {
47 global $wgUser;
48
49 $target = $request->getVal( 'target' );
50 $this->page = Title::newFromUrl( $target );
51
52 $this->revisions = $request->getIntArray( 'oldid', array() );
53
54 $this->skin = $wgUser->getSkin();
55 $this->checks = array(
56 array( 'revdelete-hide-text', 'wpHideText', Revision::DELETED_TEXT ),
57 array( 'revdelete-hide-comment', 'wpHideComment', Revision::DELETED_COMMENT ),
58 array( 'revdelete-hide-user', 'wpHideUser', Revision::DELETED_USER ),
59 array( 'revdelete-hide-restricted', 'wpHideRestricted', Revision::DELETED_RESTRICTED ) );
60 }
61
62 /**
63 * @param WebRequest $request
64 */
65 function show( $request ) {
66 global $wgOut, $wgUser;
67
68 $wgOut->addWikiMsg( 'revdelete-selected', $this->page->getPrefixedText() );
69
70 $wgOut->addHtml( "<ul>" );
71 foreach( $this->revisions as $revid ) {
72 $rev = Revision::newFromTitle( $this->page, $revid );
73 if( !isset( $rev ) ) {
74 $wgOut->showErrorPage( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
75 return;
76 }
77 $wgOut->addHtml( $this->historyLine( $rev ) );
78 $bitfields[] = $rev->mDeleted; // FIXME
79 }
80 $wgOut->addHtml( "</ul>" );
81
82 $wgOut->addWikiMsg( 'revdelete-text' );
83
84 $items = array(
85 Xml::inputLabel( wfMsg( 'revdelete-log' ), 'wpReason', 'wpReason', 60 ),
86 Xml::submitButton( wfMsg( 'revdelete-submit' ) ) );
87 $hidden = array(
88 Xml::hidden( 'wpEditToken', $wgUser->editToken() ),
89 Xml::hidden( 'target', $this->page->getPrefixedText() ) );
90 foreach( $this->revisions as $revid ) {
91 $hidden[] = Xml::hidden( 'oldid[]', $revid );
92 }
93
94 $special = SpecialPage::getTitleFor( 'Revisiondelete' );
95 $wgOut->addHtml( Xml::element( 'form', array(
96 'method' => 'post',
97 'action' => $special->getLocalUrl( 'action=submit' ) ),
98 null ) );
99
100 $wgOut->addHtml( '<fieldset><legend>' . wfMsgHtml( 'revdelete-legend' ) . '</legend>' );
101 foreach( $this->checks as $item ) {
102 list( $message, $name, $field ) = $item;
103 $wgOut->addHtml( '<div>' .
104 Xml::checkLabel( wfMsg( $message), $name, $name, $rev->isDeleted( $field ) ) .
105 '</div>' );
106 }
107 $wgOut->addHtml( '</fieldset>' );
108 foreach( $items as $item ) {
109 $wgOut->addHtml( '<p>' . $item . '</p>' );
110 }
111 foreach( $hidden as $item ) {
112 $wgOut->addHtml( $item );
113 }
114
115 $wgOut->addHtml( '</form>' );
116 }
117
118 /**
119 * @param Revision $rev
120 * @returns string
121 */
122 function historyLine( $rev ) {
123 global $wgContLang;
124 $date = $wgContLang->timeanddate( $rev->getTimestamp() );
125 return
126 "<li>" .
127 $this->skin->makeLinkObj( $this->page, $date, 'oldid=' . $rev->getId() ) .
128 " " .
129 $this->skin->revUserLink( $rev ) .
130 " " .
131 $this->skin->revComment( $rev ) .
132 "</li>";
133 }
134
135 /**
136 * @param WebRequest $request
137 */
138 function submit( $request ) {
139 $bitfield = $this->extractBitfield( $request );
140 $comment = $request->getText( 'wpReason' );
141 if( $this->save( $bitfield, $comment ) ) {
142 return $this->success( $request );
143 } else {
144 return $this->show( $request );
145 }
146 }
147
148 function success( $request ) {
149 global $wgOut;
150 $wgOut->addWikiText( 'woo' );
151 }
152
153 /**
154 * Put together a rev_deleted bitfield from the submitted checkboxes
155 * @param WebRequest $request
156 * @return int
157 */
158 function extractBitfield( $request ) {
159 $bitfield = 0;
160 foreach( $this->checks as $item ) {
161 list( /* message */ , $name, $field ) = $item;
162 if( $request->getCheck( $name ) ) {
163 $bitfield |= $field;
164 }
165 }
166 return $bitfield;
167 }
168
169 function save( $bitfield, $reason ) {
170 $dbw = wfGetDB( DB_MASTER );
171 $deleter = new RevisionDeleter( $dbw );
172 $deleter->setVisibility( $this->revisions, $bitfield, $reason );
173 }
174 }
175
176 /**
177 * Implements the actions for Revision Deletion.
178 * @addtogroup SpecialPage
179 */
180 class RevisionDeleter {
181 function __construct( $db ) {
182 $this->db = $db;
183 }
184
185 /**
186 * @param array $items list of revision ID numbers
187 * @param int $bitfield new rev_deleted value
188 * @param string $comment Comment for log records
189 */
190 function setVisibility( $items, $bitfield, $comment ) {
191 $pages = array();
192
193 // To work!
194 foreach( $items as $revid ) {
195 $rev = Revision::newFromId( $revid );
196 if( !isset( $rev ) ) {
197 return false;
198 }
199 $this->updateRevision( $rev, $bitfield );
200 $this->updateRecentChanges( $rev, $bitfield );
201
202 // For logging, maintain a count of revisions per page
203 $pageid = $rev->getPage();
204 if( isset( $pages[$pageid] ) ) {
205 $pages[$pageid]++;
206 } else {
207 $pages[$pageid] = 1;
208 }
209 }
210
211 // Clear caches...
212 foreach( $pages as $pageid => $count ) {
213 $title = Title::newFromId( $pageid );
214 $this->updatePage( $title );
215 $this->updateLog( $title, $count, $bitfield, $comment );
216 }
217
218 return true;
219 }
220
221 /**
222 * Update the revision's rev_deleted field
223 * @param Revision $rev
224 * @param int $bitfield new rev_deleted bitfield value
225 */
226 function updateRevision( $rev, $bitfield ) {
227 $this->db->update( 'revision',
228 array( 'rev_deleted' => $bitfield ),
229 array( 'rev_id' => $rev->getId() ),
230 __METHOD__ );
231 }
232
233 /**
234 * Update the revision's recentchanges record if fields have been hidden
235 * @param Revision $rev
236 * @param int $bitfield new rev_deleted bitfield value
237 */
238 function updateRecentChanges( $rev, $bitfield ) {
239 $this->db->update( 'recentchanges',
240 array(
241 'rc_user' => ($bitfield & Revision::DELETED_USER) ? 0 : $rev->getUser(),
242 'rc_user_text' => ($bitfield & Revision::DELETED_USER) ? wfMsg( 'rev-deleted-user' ) : $rev->getUserText(),
243 'rc_comment' => ($bitfield & Revision::DELETED_COMMENT) ? wfMsg( 'rev-deleted-comment' ) : $rev->getComment() ),
244 array(
245 'rc_this_oldid' => $rev->getId() ),
246 __METHOD__ );
247 }
248
249 /**
250 * Touch the page's cache invalidation timestamp; this forces cached
251 * history views to refresh, so any newly hidden or shown fields will
252 * update properly.
253 * @param Title $title
254 */
255 function updatePage( $title ) {
256 $title->invalidateCache();
257 }
258
259 /**
260 * Record a log entry on the action
261 * @param Title $title
262 * @param int $count the number of revisions altered for this page
263 * @param int $bitfield the new rev_deleted value
264 * @param string $comment
265 */
266 function updateLog( $title, $count, $bitfield, $comment ) {
267 $log = new LogPage( 'delete' );
268 $reason = "changed $count revisions to $bitfield";
269 $reason .= ": $comment";
270 $log->addEntry( 'revision', $title, $reason );
271 }
272 }
273
274