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.
7 * To try this out, set up extra permissions something like:
8 * $wgGroupPermissions['sysop']['deleterevision'] = true;
9 * $wgGroupPermissions['bureaucrat']['hiderevision'] = true;
12 function wfSpecialRevisiondelete( $par = null ) {
13 global $wgOut, $wgRequest, $wgUser;
15 $target = $wgRequest->getVal( 'target' );
16 $oldid = $wgRequest->getIntArray( 'oldid' );
18 $sk = $wgUser->getSkin();
19 $page = Title
::newFromUrl( $target );
21 if( is_null( $page ) ) {
22 $wgOut->showErrorPage( 'notargettitle', 'notargettext' );
26 if( is_null( $oldid ) ) {
27 $wgOut->showErrorPage( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
31 $form = new RevisionDeleteForm( $wgRequest );
32 if( $wgRequest->wasPosted() ) {
33 $form->submit( $wgRequest );
35 $form->show( $wgRequest );
39 class RevisionDeleteForm
{
44 function __construct( $request ) {
47 $target = $request->getVal( 'target' );
48 $this->page
= Title
::newFromUrl( $target );
50 $this->revisions
= $request->getIntArray( 'oldid', array() );
52 $this->skin
= $wgUser->getSkin();
53 $this->checks
= array(
54 array( 'revdelete-hide-text', 'wpHideText', Revision
::DELETED_TEXT
),
55 array( 'revdelete-hide-comment', 'wpHideComment', Revision
::DELETED_COMMENT
),
56 array( 'revdelete-hide-user', 'wpHideUser', Revision
::DELETED_USER
),
57 array( 'revdelete-hide-restricted', 'wpHideRestricted', Revision
::DELETED_RESTRICTED
) );
61 * @param WebRequest $request
63 function show( $request ) {
64 global $wgOut, $wgUser;
66 $wgOut->addWikiText( wfMsg( 'revdelete-selected', $this->page
->getPrefixedText() ) );
68 $wgOut->addHtml( "<ul>" );
69 foreach( $this->revisions
as $revid ) {
70 $rev = Revision
::newFromTitle( $this->page
, $revid );
71 if( !isset( $rev ) ) {
72 $wgOut->showErrorPage( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
75 $wgOut->addHtml( $this->historyLine( $rev ) );
76 $bitfields[] = $rev->mDeleted
; // FIXME
78 $wgOut->addHtml( "</ul>" );
80 $wgOut->addWikiText( wfMsg( 'revdelete-text' ) );
83 wfInputLabel( wfMsg( 'revdelete-log' ), 'wpReason', 'wpReason', 60 ),
84 wfSubmitButton( wfMsg( 'revdelete-submit' ) ) );
86 wfHidden( 'wpEditToken', $wgUser->editToken() ),
87 wfHidden( 'target', $this->page
->getPrefixedText() ) );
88 foreach( $this->revisions
as $revid ) {
89 $hidden[] = wfHidden( 'oldid[]', $revid );
92 $special = Title
::makeTitle( NS_SPECIAL
, 'Revisiondelete' );
93 $wgOut->addHtml( wfElement( 'form', array(
95 'action' => $special->getLocalUrl( 'action=submit' ) ),
98 $wgOut->addHtml( '<fieldset><legend>' . wfMsgHtml( 'revdelete-legend' ) . '</legend>' );
99 foreach( $this->checks
as $item ) {
100 list( $message, $name, $field ) = $item;
101 $wgOut->addHtml( '<div>' .
102 wfCheckLabel( wfMsg( $message), $name, $name, $rev->isDeleted( $field ) ) .
105 $wgOut->addHtml( '</fieldset>' );
106 foreach( $items as $item ) {
107 $wgOut->addHtml( '<p>' . $item . '</p>' );
109 foreach( $hidden as $item ) {
110 $wgOut->addHtml( $item );
113 $wgOut->addHtml( '</form>' );
117 * @param Revision $rev
120 function historyLine( $rev ) {
122 $date = $wgContLang->timeanddate( $rev->getTimestamp() );
125 $this->skin
->makeLinkObj( $this->page
, $date, 'oldid=' . $rev->getId() ) .
127 $this->skin
->revUserLink( $rev ) .
129 $this->skin
->revComment( $rev ) .
134 * @param WebRequest $request
136 function submit( $request ) {
137 $bitfield = $this->extractBitfield( $request );
138 $comment = $request->getText( 'wpReason' );
139 if( $this->save( $bitfield, $comment ) ) {
140 return $this->success( $request );
142 return $this->show( $request );
146 function success( $request ) {
148 $wgOut->addWikiText( 'woo' );
152 * Put together a rev_deleted bitfield from the submitted checkboxes
153 * @param WebRequest $request
156 function extractBitfield( $request ) {
158 foreach( $this->checks
as $item ) {
159 list( $message, $name, $field ) = $item;
160 if( $request->getCheck( $name ) ) {
167 function save( $bitfield, $reason ) {
168 $dbw = wfGetDB( DB_MASTER
);
169 $deleter = new RevisionDeleter( $dbw );
170 $ok = $deleter->setVisibility( $this->revisions
, $bitfield, $reason );
175 class RevisionDeleter
{
176 function __construct( $db ) {
181 * @param array $items list of revision ID numbers
182 * @param int $bitfield new rev_deleted value
183 * @param string $comment Comment for log records
185 function setVisibility( $items, $bitfield, $comment ) {
189 foreach( $items as $revid ) {
190 $rev = Revision
::newFromId( $revid );
191 if( !isset( $rev ) ) {
194 $this->updateRevision( $rev, $bitfield );
195 $this->updateRecentChanges( $rev, $bitfield );
197 // For logging, maintain a count of revisions per page
198 $pageid = $rev->getPage();
199 if( isset( $pages[$pageid] ) ) {
207 foreach( $pages as $pageid => $count ) {
208 $title = Title
::newFromId( $pageid );
209 $this->updatePage( $title );
210 $this->updateLog( $title, $count, $bitfield, $comment );
217 * Update the revision's rev_deleted field
218 * @param Revision $rev
219 * @param int $bitfield new rev_deleted bitfield value
221 function updateRevision( $rev, $bitfield ) {
222 $this->db
->update( 'revision',
223 array( 'rev_deleted' => $bitfield ),
224 array( 'rev_id' => $rev->getId() ),
225 'RevisionDeleter::updateRevision' );
229 * Update the revision's recentchanges record if fields have been hidden
230 * @param Revision $rev
231 * @param int $bitfield new rev_deleted bitfield value
233 function updateRecentChanges( $rev, $bitfield ) {
234 $this->db
->update( 'recentchanges',
236 'rc_user' => ($bitfield & Revision
::DELETED_USER
) ?
0 : $rev->getUser(),
237 'rc_user_text' => ($bitfield & Revision
::DELETED_USER
) ?
wfMsg( 'rev-deleted-user' ) : $rev->getUserText(),
238 'rc_comment' => ($bitfield & Revision
::DELETED_COMMENT
) ?
wfMsg( 'rev-deleted-comment' ) : $rev->getComment() ),
240 'rc_this_oldid' => $rev->getId() ),
241 'RevisionDeleter::updateRecentChanges' );
245 * Touch the page's cache invalidation timestamp; this forces cached
246 * history views to refresh, so any newly hidden or shown fields will
248 * @param Title $title
250 function updatePage( $title ) {
251 $title->invalidateCache();
255 * Record a log entry on the action
256 * @param Title $title
257 * @param int $count the number of revisions altered for this page
258 * @param int $bitfield the new rev_deleted value
259 * @param string $comment
261 function updateLog( $title, $count, $bitfield, $comment ) {
262 $log = new LogPage( 'delete' );
263 $reason = "changed $count revisions to $bitfield";
264 $reason .= ": $comment";
265 $log->addEntry( 'revision', $title, $reason );