Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 124 |
|
0.00% |
0 / 20 |
CRAP | |
0.00% |
0 / 1 |
RevDelFileItem | |
0.00% |
0 / 124 |
|
0.00% |
0 / 20 |
1122 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
initFile | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
getIdField | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getTimestampField | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getAuthorIdField | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getAuthorNameField | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getAuthorActorField | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getId | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
canView | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
canViewContent | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getBits | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setBits | |
0.00% |
0 / 25 |
|
0.00% |
0 / 1 |
20 | |||
isDeleted | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getLink | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
12 | |||
getUserTools | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
12 | |||
getComment | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
12 | |||
getHTML | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
getApiData | |
0.00% |
0 / 39 |
|
0.00% |
0 / 1 |
30 | |||
lock | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
unlock | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
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 | |
22 | use MediaWiki\Api\ApiResult; |
23 | use MediaWiki\Html\Html; |
24 | use MediaWiki\Linker\Linker; |
25 | use MediaWiki\MediaWikiServices; |
26 | use MediaWiki\RevisionList\RevisionListBase; |
27 | use MediaWiki\SpecialPage\SpecialPage; |
28 | use Wikimedia\Rdbms\IConnectionProvider; |
29 | |
30 | /** |
31 | * Item class for an oldimage table row |
32 | */ |
33 | class RevDelFileItem extends RevDelItem { |
34 | /** @var RevDelFileList */ |
35 | protected $list; |
36 | /** @var OldLocalFile */ |
37 | protected $file; |
38 | protected IConnectionProvider $dbProvider; |
39 | |
40 | public function __construct( RevisionListBase $list, $row ) { |
41 | parent::__construct( $list, $row ); |
42 | $this->file = static::initFile( $list, $row ); |
43 | $this->dbProvider = MediaWikiServices::getInstance()->getConnectionProvider(); |
44 | } |
45 | |
46 | /** |
47 | * Create file object from $row sourced from $list |
48 | * |
49 | * @param RevisionListBase $list |
50 | * @param mixed $row |
51 | * @return mixed |
52 | */ |
53 | protected static function initFile( $list, $row ) { |
54 | return MediaWikiServices::getInstance()->getRepoGroup()->getLocalRepo() |
55 | ->newFileFromRow( $row ); |
56 | } |
57 | |
58 | public function getIdField() { |
59 | return 'oi_archive_name'; |
60 | } |
61 | |
62 | public function getTimestampField() { |
63 | return 'oi_timestamp'; |
64 | } |
65 | |
66 | public function getAuthorIdField() { |
67 | return 'oi_user'; |
68 | } |
69 | |
70 | public function getAuthorNameField() { |
71 | return 'oi_user_text'; |
72 | } |
73 | |
74 | public function getAuthorActorField() { |
75 | return 'oi_actor'; |
76 | } |
77 | |
78 | public function getId() { |
79 | $parts = explode( '!', $this->row->oi_archive_name ); |
80 | |
81 | return $parts[0]; |
82 | } |
83 | |
84 | public function canView() { |
85 | return $this->file->userCan( File::DELETED_RESTRICTED, $this->list->getAuthority() ); |
86 | } |
87 | |
88 | public function canViewContent() { |
89 | return $this->file->userCan( File::DELETED_FILE, $this->list->getAuthority() ); |
90 | } |
91 | |
92 | public function getBits() { |
93 | return $this->file->getVisibility(); |
94 | } |
95 | |
96 | public function setBits( $bits ) { |
97 | # Queue the file op |
98 | # @todo FIXME: Move to LocalFile.php |
99 | if ( $this->isDeleted() ) { |
100 | if ( $bits & File::DELETED_FILE ) { |
101 | # Still deleted |
102 | } else { |
103 | # Newly undeleted |
104 | $key = $this->file->getStorageKey(); |
105 | $srcRel = $this->file->repo->getDeletedHashPath( $key ) . $key; |
106 | $this->list->storeBatch[] = [ |
107 | $this->file->repo->getVirtualUrl( 'deleted' ) . '/' . $srcRel, |
108 | 'public', |
109 | $this->file->getRel() |
110 | ]; |
111 | $this->list->cleanupBatch[] = $key; |
112 | } |
113 | } elseif ( $bits & File::DELETED_FILE ) { |
114 | # Newly deleted |
115 | $key = $this->file->getStorageKey(); |
116 | $dstRel = $this->file->repo->getDeletedHashPath( $key ) . $key; |
117 | $this->list->deleteBatch[] = [ $this->file->getRel(), $dstRel ]; |
118 | } |
119 | |
120 | # Do the database operations |
121 | $dbw = $this->dbProvider->getPrimaryDatabase(); |
122 | $dbw->newUpdateQueryBuilder() |
123 | ->update( 'oldimage' ) |
124 | ->set( [ 'oi_deleted' => $bits ] ) |
125 | ->where( [ |
126 | 'oi_name' => $this->row->oi_name, |
127 | 'oi_timestamp' => $this->row->oi_timestamp, |
128 | 'oi_deleted' => $this->getBits() |
129 | ] ) |
130 | ->caller( __METHOD__ )->execute(); |
131 | |
132 | return (bool)$dbw->affectedRows(); |
133 | } |
134 | |
135 | public function isDeleted() { |
136 | return $this->file->isDeleted( File::DELETED_FILE ); |
137 | } |
138 | |
139 | /** |
140 | * Get the link to the file. |
141 | * Overridden by RevDelArchivedFileItem. |
142 | * @return string |
143 | */ |
144 | protected function getLink() { |
145 | $date = $this->list->getLanguage()->userTimeAndDate( |
146 | $this->file->getTimestamp(), $this->list->getUser() ); |
147 | |
148 | if ( !$this->isDeleted() ) { |
149 | # Regular files... |
150 | return Html::element( 'a', [ 'href' => $this->file->getUrl() ], $date ); |
151 | } |
152 | |
153 | # Hidden files... |
154 | if ( !$this->canViewContent() ) { |
155 | $link = htmlspecialchars( $date ); |
156 | } else { |
157 | $link = $this->getLinkRenderer()->makeLink( |
158 | SpecialPage::getTitleFor( 'Revisiondelete' ), |
159 | $date, |
160 | [], |
161 | [ |
162 | 'target' => $this->list->getPageName(), |
163 | 'file' => $this->file->getArchiveName(), |
164 | 'token' => $this->list->getUser()->getEditToken( |
165 | $this->file->getArchiveName() ) |
166 | ] |
167 | ); |
168 | } |
169 | |
170 | return '<span class="history-deleted">' . $link . '</span>'; |
171 | } |
172 | |
173 | /** |
174 | * Generate a user tool link cluster if the current user is allowed to view it |
175 | * @return string HTML |
176 | */ |
177 | protected function getUserTools() { |
178 | $uploader = $this->file->getUploader( File::FOR_THIS_USER, $this->list->getAuthority() ); |
179 | if ( $uploader ) { |
180 | $link = Linker::userLink( $uploader->getId(), $uploader->getName() ) . |
181 | Linker::userToolLinks( $uploader->getId(), $uploader->getName() ); |
182 | return $link; |
183 | } else { |
184 | $link = $this->list->msg( 'rev-deleted-user' )->escaped(); |
185 | } |
186 | if ( $this->file->isDeleted( File::DELETED_USER ) ) { |
187 | return '<span class="history-deleted">' . $link . '</span>'; |
188 | } |
189 | return $link; |
190 | } |
191 | |
192 | /** |
193 | * Wrap and format the file's comment block, if the current |
194 | * user is allowed to view it. |
195 | * |
196 | * @return string HTML |
197 | */ |
198 | protected function getComment() { |
199 | if ( $this->file->userCan( File::DELETED_COMMENT, $this->list->getAuthority() ) ) { |
200 | $block = MediaWikiServices::getInstance()->getCommentFormatter() |
201 | ->formatBlock( $this->file->getDescription() ); |
202 | } else { |
203 | $block = ' ' . $this->list->msg( 'rev-deleted-comment' )->escaped(); |
204 | } |
205 | if ( $this->file->isDeleted( File::DELETED_COMMENT ) ) { |
206 | return "<span class=\"history-deleted\">$block</span>"; |
207 | } |
208 | |
209 | return $block; |
210 | } |
211 | |
212 | public function getHTML() { |
213 | $data = |
214 | $this->list->msg( 'widthheight' )->numParams( |
215 | $this->file->getWidth(), |
216 | $this->file->getHeight() )->escaped() . |
217 | ' (' . $this->list->msg( 'nbytes' )->numParams( |
218 | $this->file->getSize() )->escaped() . ')'; |
219 | |
220 | return '<li>' . $this->getLink() . ' ' . $this->getUserTools() . ' ' . |
221 | $data . ' ' . $this->getComment() . '</li>'; |
222 | } |
223 | |
224 | public function getApiData( ApiResult $result ) { |
225 | $file = $this->file; |
226 | $user = $this->list->getUser(); |
227 | $ret = [ |
228 | 'title' => $this->list->getPageName(), |
229 | 'archivename' => $file->getArchiveName(), |
230 | 'timestamp' => wfTimestamp( TS_ISO_8601, $file->getTimestamp() ), |
231 | 'width' => $file->getWidth(), |
232 | 'height' => $file->getHeight(), |
233 | 'size' => $file->getSize(), |
234 | 'userhidden' => (bool)$file->isDeleted( File::DELETED_USER ), |
235 | 'commenthidden' => (bool)$file->isDeleted( File::DELETED_COMMENT ), |
236 | 'contenthidden' => (bool)$this->isDeleted(), |
237 | ]; |
238 | if ( !$this->isDeleted() ) { |
239 | $ret += [ |
240 | 'url' => $file->getUrl(), |
241 | ]; |
242 | } elseif ( $this->canViewContent() ) { |
243 | $ret += [ |
244 | 'url' => SpecialPage::getTitleFor( 'Revisiondelete' )->getLinkURL( |
245 | [ |
246 | 'target' => $this->list->getPageName(), |
247 | 'file' => $file->getArchiveName(), |
248 | 'token' => $user->getEditToken( $file->getArchiveName() ) |
249 | ] |
250 | ), |
251 | ]; |
252 | } |
253 | $uploader = $file->getUploader( File::FOR_THIS_USER, $user ); |
254 | if ( $uploader ) { |
255 | $ret += [ |
256 | 'userid' => $uploader->getId(), |
257 | 'user' => $uploader->getName(), |
258 | ]; |
259 | } |
260 | $comment = $file->getDescription( File::FOR_THIS_USER, $user ); |
261 | if ( ( $comment ?? '' ) !== '' ) { |
262 | $ret += [ |
263 | 'comment' => $comment, |
264 | ]; |
265 | } |
266 | |
267 | return $ret; |
268 | } |
269 | |
270 | public function lock() { |
271 | return $this->file->acquireFileLock(); |
272 | } |
273 | |
274 | public function unlock() { |
275 | return $this->file->releaseFileLock(); |
276 | } |
277 | } |