RevDelFileItem.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. <?php
  2. /**
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along
  14. * with this program; if not, write to the Free Software Foundation, Inc.,
  15. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. * http://www.gnu.org/copyleft/gpl.html
  17. *
  18. * @file
  19. * @ingroup RevisionDelete
  20. */
  21. use MediaWiki\Revision\RevisionRecord;
  22. /**
  23. * Item class for an oldimage table row
  24. */
  25. class RevDelFileItem extends RevDelItem {
  26. /** @var RevDelFileList */
  27. protected $list;
  28. /** @var OldLocalFile */
  29. protected $file;
  30. public function __construct( $list, $row ) {
  31. parent::__construct( $list, $row );
  32. $this->file = static::initFile( $list, $row );
  33. }
  34. /**
  35. * Create file object from $row sourced from $list
  36. *
  37. * @param RevDelFileList $list
  38. * @param mixed $row
  39. * @return mixed
  40. */
  41. protected static function initFile( $list, $row ) {
  42. return RepoGroup::singleton()->getLocalRepo()->newFileFromRow( $row );
  43. }
  44. public function getIdField() {
  45. return 'oi_archive_name';
  46. }
  47. public function getTimestampField() {
  48. return 'oi_timestamp';
  49. }
  50. public function getAuthorIdField() {
  51. return 'oi_user';
  52. }
  53. public function getAuthorNameField() {
  54. return 'oi_user_text';
  55. }
  56. public function getAuthorActorField() {
  57. return 'oi_actor';
  58. }
  59. public function getId() {
  60. $parts = explode( '!', $this->row->oi_archive_name );
  61. return $parts[0];
  62. }
  63. public function canView() {
  64. return $this->file->userCan( File::DELETED_RESTRICTED, $this->list->getUser() );
  65. }
  66. public function canViewContent() {
  67. return $this->file->userCan( File::DELETED_FILE, $this->list->getUser() );
  68. }
  69. public function getBits() {
  70. return $this->file->getVisibility();
  71. }
  72. public function setBits( $bits ) {
  73. # Queue the file op
  74. # @todo FIXME: Move to LocalFile.php
  75. if ( $this->isDeleted() ) {
  76. if ( $bits & File::DELETED_FILE ) {
  77. # Still deleted
  78. } else {
  79. # Newly undeleted
  80. $key = $this->file->getStorageKey();
  81. $srcRel = $this->file->repo->getDeletedHashPath( $key ) . $key;
  82. $this->list->storeBatch[] = [
  83. $this->file->repo->getVirtualUrl( 'deleted' ) . '/' . $srcRel,
  84. 'public',
  85. $this->file->getRel()
  86. ];
  87. $this->list->cleanupBatch[] = $key;
  88. }
  89. } elseif ( $bits & File::DELETED_FILE ) {
  90. # Newly deleted
  91. $key = $this->file->getStorageKey();
  92. $dstRel = $this->file->repo->getDeletedHashPath( $key ) . $key;
  93. $this->list->deleteBatch[] = [ $this->file->getRel(), $dstRel ];
  94. }
  95. # Do the database operations
  96. $dbw = wfGetDB( DB_MASTER );
  97. $dbw->update( 'oldimage',
  98. [ 'oi_deleted' => $bits ],
  99. [
  100. 'oi_name' => $this->row->oi_name,
  101. 'oi_timestamp' => $this->row->oi_timestamp,
  102. 'oi_deleted' => $this->getBits()
  103. ],
  104. __METHOD__
  105. );
  106. return (bool)$dbw->affectedRows();
  107. }
  108. public function isDeleted() {
  109. return $this->file->isDeleted( File::DELETED_FILE );
  110. }
  111. /**
  112. * Get the link to the file.
  113. * Overridden by RevDelArchivedFileItem.
  114. * @return string
  115. */
  116. protected function getLink() {
  117. $date = $this->list->getLanguage()->userTimeAndDate(
  118. $this->file->getTimestamp(), $this->list->getUser() );
  119. if ( !$this->isDeleted() ) {
  120. # Regular files...
  121. return Html::element( 'a', [ 'href' => $this->file->getUrl() ], $date );
  122. }
  123. # Hidden files...
  124. if ( !$this->canViewContent() ) {
  125. $link = htmlspecialchars( $date );
  126. } else {
  127. $link = $this->getLinkRenderer()->makeLink(
  128. SpecialPage::getTitleFor( 'Revisiondelete' ),
  129. $date,
  130. [],
  131. [
  132. 'target' => $this->list->title->getPrefixedText(),
  133. 'file' => $this->file->getArchiveName(),
  134. 'token' => $this->list->getUser()->getEditToken(
  135. $this->file->getArchiveName() )
  136. ]
  137. );
  138. }
  139. return '<span class="history-deleted">' . $link . '</span>';
  140. }
  141. /**
  142. * Generate a user tool link cluster if the current user is allowed to view it
  143. * @return string HTML
  144. */
  145. protected function getUserTools() {
  146. if ( $this->file->userCan( RevisionRecord::DELETED_USER, $this->list->getUser() ) ) {
  147. $uid = $this->file->getUser( 'id' );
  148. $name = $this->file->getUser( 'text' );
  149. $link = Linker::userLink( $uid, $name ) . Linker::userToolLinks( $uid, $name );
  150. } else {
  151. $link = $this->list->msg( 'rev-deleted-user' )->escaped();
  152. }
  153. if ( $this->file->isDeleted( RevisionRecord::DELETED_USER ) ) {
  154. return '<span class="history-deleted">' . $link . '</span>';
  155. }
  156. return $link;
  157. }
  158. /**
  159. * Wrap and format the file's comment block, if the current
  160. * user is allowed to view it.
  161. *
  162. * @return string HTML
  163. */
  164. protected function getComment() {
  165. if ( $this->file->userCan( File::DELETED_COMMENT, $this->list->getUser() ) ) {
  166. $block = Linker::commentBlock( $this->file->getDescription() );
  167. } else {
  168. $block = ' ' . $this->list->msg( 'rev-deleted-comment' )->escaped();
  169. }
  170. if ( $this->file->isDeleted( File::DELETED_COMMENT ) ) {
  171. return "<span class=\"history-deleted\">$block</span>";
  172. }
  173. return $block;
  174. }
  175. public function getHTML() {
  176. $data =
  177. $this->list->msg( 'widthheight' )->numParams(
  178. $this->file->getWidth(), $this->file->getHeight() )->text() .
  179. ' (' . $this->list->msg( 'nbytes' )->numParams( $this->file->getSize() )->text() . ')';
  180. return '<li>' . $this->getLink() . ' ' . $this->getUserTools() . ' ' .
  181. $data . ' ' . $this->getComment() . '</li>';
  182. }
  183. public function getApiData( ApiResult $result ) {
  184. $file = $this->file;
  185. $user = $this->list->getUser();
  186. $ret = [
  187. 'title' => $this->list->title->getPrefixedText(),
  188. 'archivename' => $file->getArchiveName(),
  189. 'timestamp' => wfTimestamp( TS_ISO_8601, $file->getTimestamp() ),
  190. 'width' => $file->getWidth(),
  191. 'height' => $file->getHeight(),
  192. 'size' => $file->getSize(),
  193. 'userhidden' => (bool)$file->isDeleted( RevisionRecord::DELETED_USER ),
  194. 'commenthidden' => (bool)$file->isDeleted( RevisionRecord::DELETED_COMMENT ),
  195. 'contenthidden' => (bool)$this->isDeleted(),
  196. ];
  197. if ( !$this->isDeleted() ) {
  198. $ret += [
  199. 'url' => $file->getUrl(),
  200. ];
  201. } elseif ( $this->canViewContent() ) {
  202. $ret += [
  203. 'url' => SpecialPage::getTitleFor( 'Revisiondelete' )->getLinkURL(
  204. [
  205. 'target' => $this->list->title->getPrefixedText(),
  206. 'file' => $file->getArchiveName(),
  207. 'token' => $user->getEditToken( $file->getArchiveName() )
  208. ]
  209. ),
  210. ];
  211. }
  212. if ( $file->userCan( RevisionRecord::DELETED_USER, $user ) ) {
  213. $ret += [
  214. 'userid' => $file->user,
  215. 'user' => $file->user_text,
  216. ];
  217. }
  218. if ( $file->userCan( RevisionRecord::DELETED_COMMENT, $user ) ) {
  219. $ret += [
  220. 'comment' => $file->description,
  221. ];
  222. }
  223. return $ret;
  224. }
  225. public function lock() {
  226. return $this->file->acquireFileLock();
  227. }
  228. public function unlock() {
  229. return $this->file->releaseFileLock();
  230. }
  231. }