PageRenderTime 45ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/mediawiki-integration/source/php/mediawiki/includes/SpecialRevisiondelete.php

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