RevertAction.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <?php
  2. /**
  3. * File reversion user interface
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  18. *
  19. * @file
  20. * @ingroup Actions
  21. * @ingroup Media
  22. * @author Alexandre Emsenhuber
  23. * @author Rob Church <robchur@gmail.com>
  24. */
  25. use MediaWiki\MediaWikiServices;
  26. /**
  27. * File reversion user interface
  28. *
  29. * @ingroup Actions
  30. */
  31. class RevertAction extends FormAction {
  32. /**
  33. * @var OldLocalFile
  34. */
  35. protected $oldFile;
  36. public function getName() {
  37. return 'revert';
  38. }
  39. public function getRestriction() {
  40. return 'upload';
  41. }
  42. protected function checkCanExecute( User $user ) {
  43. if ( $this->getTitle()->getNamespace() !== NS_FILE ) {
  44. throw new ErrorPageError( $this->msg( 'nosuchaction' ), $this->msg( 'nosuchactiontext' ) );
  45. }
  46. parent::checkCanExecute( $user );
  47. $oldimage = $this->getRequest()->getText( 'oldimage' );
  48. if ( strlen( $oldimage ) < 16
  49. || strpos( $oldimage, '/' ) !== false
  50. || strpos( $oldimage, '\\' ) !== false
  51. ) {
  52. throw new ErrorPageError( 'internalerror', 'unexpected', [ 'oldimage', $oldimage ] );
  53. }
  54. $this->oldFile = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName(
  55. $this->getTitle(),
  56. $oldimage
  57. );
  58. if ( !$this->oldFile->exists() ) {
  59. throw new ErrorPageError( '', 'filerevert-badversion' );
  60. }
  61. }
  62. protected function usesOOUI() {
  63. return true;
  64. }
  65. protected function alterForm( HTMLForm $form ) {
  66. $form->setWrapperLegendMsg( 'filerevert-legend' );
  67. $form->setSubmitTextMsg( 'filerevert-submit' );
  68. $form->addHiddenField( 'oldimage', $this->getRequest()->getText( 'oldimage' ) );
  69. $form->setTokenSalt( [ 'revert', $this->getTitle()->getPrefixedDBkey() ] );
  70. }
  71. protected function getFormFields() {
  72. $timestamp = $this->oldFile->getTimestamp();
  73. $user = $this->getUser();
  74. $lang = $this->getLanguage();
  75. $userDate = $lang->userDate( $timestamp, $user );
  76. $userTime = $lang->userTime( $timestamp, $user );
  77. $siteTs = MWTimestamp::getLocalInstance( $timestamp );
  78. $ts = $siteTs->format( 'YmdHis' );
  79. $contLang = MediaWikiServices::getInstance()->getContentLanguage();
  80. $siteDate = $contLang->date( $ts, false, false );
  81. $siteTime = $contLang->time( $ts, false, false );
  82. $tzMsg = $siteTs->getTimezoneMessage()->inContentLanguage()->text();
  83. return [
  84. 'intro' => [
  85. 'type' => 'info',
  86. 'vertical-label' => true,
  87. 'raw' => true,
  88. 'default' => $this->msg( 'filerevert-intro',
  89. $this->getTitle()->getText(), $userDate, $userTime,
  90. wfExpandUrl(
  91. $this->page->getFile()->getArchiveUrl( $this->getRequest()->getText( 'oldimage' ) ),
  92. PROTO_CURRENT
  93. ) )->parseAsBlock()
  94. ],
  95. 'comment' => [
  96. 'type' => 'text',
  97. 'label-message' => 'filerevert-comment',
  98. 'default' => $this->msg( 'filerevert-defaultcomment', $siteDate, $siteTime,
  99. $tzMsg )->inContentLanguage()->text()
  100. ]
  101. ];
  102. }
  103. public function onSubmit( $data ) {
  104. $this->useTransactionalTimeLimit();
  105. $old = $this->getRequest()->getText( 'oldimage' );
  106. /** @var LocalFile $localFile */
  107. $localFile = $this->page->getFile();
  108. '@phan-var LocalFile $localFile';
  109. $oldFile = OldLocalFile::newFromArchiveName( $this->getTitle(), $localFile->getRepo(), $old );
  110. $source = $localFile->getArchiveVirtualUrl( $old );
  111. $comment = $data['comment'];
  112. if ( $localFile->getSha1() === $oldFile->getSha1() ) {
  113. return Status::newFatal( 'filerevert-identical' );
  114. }
  115. // TODO: Preserve file properties from database instead of reloading from file
  116. return $localFile->upload(
  117. $source,
  118. $comment,
  119. $comment,
  120. 0,
  121. false,
  122. false,
  123. $this->getUser(),
  124. [],
  125. true,
  126. true
  127. );
  128. }
  129. public function onSuccess() {
  130. $timestamp = $this->oldFile->getTimestamp();
  131. $user = $this->getUser();
  132. $lang = $this->getLanguage();
  133. $userDate = $lang->userDate( $timestamp, $user );
  134. $userTime = $lang->userTime( $timestamp, $user );
  135. $this->getOutput()->addWikiMsg( 'filerevert-success', $this->getTitle()->getText(),
  136. $userDate, $userTime,
  137. wfExpandUrl( $this->page->getFile()->getArchiveUrl( $this->getRequest()->getText( 'oldimage' ) ),
  138. PROTO_CURRENT
  139. ) );
  140. $this->getOutput()->returnToMain( false, $this->getTitle() );
  141. }
  142. protected function getPageTitle() {
  143. return $this->msg( 'filerevert', $this->getTitle()->getText() );
  144. }
  145. protected function getDescription() {
  146. return OutputPage::buildBacklinkSubtitle( $this->getTitle() );
  147. }
  148. public function doesWrites() {
  149. return true;
  150. }
  151. }