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