MediaWiki  master
ImageHistoryList.php
Go to the documentation of this file.
1 <?php
21 use MediaWiki\HookContainer\ProtectedHookAccessorTrait;
23 
30  use ProtectedHookAccessorTrait;
31 
35  protected $title;
36 
40  protected $img;
41 
45  protected $imagePage;
46 
50  protected $current;
51 
52  protected $repo, $showThumb;
53  protected $preventClickjacking = false;
54 
58  public function __construct( $imagePage ) {
60  $this->current = $imagePage->getPage()->getFile();
61  $this->img = $imagePage->getDisplayedFile();
62  $this->title = $imagePage->getTitle();
63  $this->imagePage = $imagePage;
64  $this->showThumb = $context->getConfig()->get( 'ShowArchiveThumbnails' ) &&
65  $this->img->canRender();
66  $this->setContext( $context );
67  }
68 
72  public function getImagePage() {
73  return $this->imagePage;
74  }
75 
79  public function getFile() {
80  return $this->img;
81  }
82 
87  public function beginImageHistoryList( $navLinks = '' ) {
88  return Xml::element( 'h2', [ 'id' => 'filehistory' ], $this->msg( 'filehist' )->text() )
89  . "\n"
90  . "<div id=\"mw-imagepage-section-filehistory\">\n"
91  . $this->msg( 'filehist-help' )->parseAsBlock()
92  . $navLinks . "\n"
93  . Xml::openElement( 'table', [ 'class' => 'wikitable filehistory' ] ) . "\n"
94  . '<tr><th></th>'
95  . ( $this->current->isLocal()
96  && ( $this->getAuthority()->isAllowedAny( 'delete', 'deletedhistory' ) ) ? '<th></th>' : '' )
97  . '<th>' . $this->msg( 'filehist-datetime' )->escaped() . '</th>'
98  . ( $this->showThumb ? '<th>' . $this->msg( 'filehist-thumb' )->escaped() . '</th>' : '' )
99  . '<th>' . $this->msg( 'filehist-dimensions' )->escaped() . '</th>'
100  . '<th>' . $this->msg( 'filehist-user' )->escaped() . '</th>'
101  . '<th>' . $this->msg( 'filehist-comment' )->escaped() . '</th>'
102  . "</tr>\n";
103  }
104 
109  public function endImageHistoryList( $navLinks = '' ) {
110  return "</table>\n$navLinks\n</div>\n";
111  }
112 
118  public function imageHistoryLine( $iscur, $file ) {
119  $user = $this->getUser();
120  $lang = $this->getLanguage();
121  $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
122  $timestamp = wfTimestamp( TS_MW, $file->getTimestamp() );
123  // @phan-suppress-next-line PhanUndeclaredMethod
124  $img = $iscur ? $file->getName() : $file->getArchiveName();
125  $userId = $file->getUser( 'id' );
126  $userText = $file->getUser( 'text' );
127  $description = $file->getDescription( File::FOR_THIS_USER, $user );
128 
129  $local = $this->current->isLocal();
130  $row = $selected = '';
131 
132  // Deletion link
133  if ( $local && ( $this->getAuthority()->isAllowedAny( 'delete', 'deletedhistory' ) ) ) {
134  $row .= '<td>';
135  # Link to remove from history
136  if ( $this->getAuthority()->isAllowed( 'delete' ) ) {
137  $q = [ 'action' => 'delete' ];
138  if ( !$iscur ) {
139  $q['oldimage'] = $img;
140  }
141  $row .= $linkRenderer->makeKnownLink(
142  $this->title,
143  $this->msg( $iscur ? 'filehist-deleteall' : 'filehist-deleteone' )->text(),
144  [], $q
145  );
146  }
147  # Link to hide content. Don't show useless link to people who cannot hide revisions.
148  $canHide = $this->getAuthority()->isAllowed( 'deleterevision' );
149  if ( $canHide || ( $this->getAuthority()->isAllowed( 'deletedhistory' )
150  && $file->getVisibility() ) ) {
151  if ( $this->getAuthority()->isAllowed( 'delete' ) ) {
152  $row .= '<br />';
153  }
154  // If file is top revision or locked from this user, don't link
155  if ( $iscur || !$file->userCan( File::DELETED_RESTRICTED, $user ) ) {
156  $del = Linker::revDeleteLinkDisabled( $canHide );
157  } else {
158  list( $ts, ) = explode( '!', $img, 2 );
159  $query = [
160  'type' => 'oldimage',
161  'target' => $this->title->getPrefixedText(),
162  'ids' => $ts,
163  ];
164  $del = Linker::revDeleteLink( $query,
165  $file->isDeleted( File::DELETED_RESTRICTED ), $canHide );
166  }
167  $row .= $del;
168  }
169  $row .= '</td>';
170  }
171 
172  // Reversion link/current indicator
173  $row .= '<td>';
174  if ( $iscur ) {
175  $row .= $this->msg( 'filehist-current' )->escaped();
176  } elseif ( $local && $this->getAuthority()->probablyCan( 'edit', $this->title )
177  && $this->getAuthority()->probablyCan( 'upload', $this->title )
178  ) {
179  if ( $file->isDeleted( File::DELETED_FILE ) ) {
180  $row .= $this->msg( 'filehist-revert' )->escaped();
181  } else {
182  $row .= $linkRenderer->makeKnownLink(
183  $this->title,
184  $this->msg( 'filehist-revert' )->text(),
185  [],
186  [
187  'action' => 'revert',
188  'oldimage' => $img,
189  ]
190  );
191  }
192  }
193  $row .= '</td>';
194 
195  // Date/time and image link
196  if ( $file->getTimestamp() === $this->img->getTimestamp() ) {
197  $selected = "class='filehistory-selected'";
198  }
199  $row .= "<td $selected style='white-space: nowrap;'>";
200  if ( !$file->userCan( File::DELETED_FILE, $user ) ) {
201  # Don't link to unviewable files
202  $row .= Html::element( 'span', [ 'class' => 'history-deleted' ],
203  $lang->userTimeAndDate( $timestamp, $user )
204  );
205  } elseif ( $file->isDeleted( File::DELETED_FILE ) ) {
206  $timeAndDate = $lang->userTimeAndDate( $timestamp, $user );
207  if ( $local ) {
208  $this->preventClickjacking();
209  $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
210  # Make a link to review the image
211  $url = $linkRenderer->makeKnownLink(
212  $revdel,
213  $timeAndDate,
214  [],
215  [
216  'target' => $this->title->getPrefixedText(),
217  'file' => $img,
218  'token' => $user->getEditToken( $img )
219  ]
220  );
221  } else {
222  $url = htmlspecialchars( $timeAndDate );
223  }
224  $row .= '<span class="history-deleted">' . $url . '</span>';
225  } elseif ( !$file->exists() ) {
226  $row .= Html::element( 'span', [ 'class' => 'mw-file-missing' ],
227  $lang->userTimeAndDate( $timestamp, $user )
228  );
229  } else {
230  $url = $iscur ? $this->current->getUrl() : $this->current->getArchiveUrl( $img );
231  $row .= Xml::element(
232  'a',
233  [ 'href' => $url ],
234  $lang->userTimeAndDate( $timestamp, $user )
235  );
236  }
237  $row .= "</td>";
238 
239  // Thumbnail
240  if ( $this->showThumb ) {
241  $row .= '<td>' . $this->getThumbForLine( $file ) . '</td>';
242  }
243 
244  // Image dimensions + size
245  $row .= '<td>';
246  $row .= htmlspecialchars( $file->getDimensionsString() );
247  $row .= $this->msg( 'word-separator' )->escaped();
248  $row .= '<span style="white-space: nowrap;">';
249  $row .= $this->msg( 'parentheses' )->sizeParams( $file->getSize() )->escaped();
250  $row .= '</span>';
251  $row .= '</td>';
252 
253  // Uploading user
254  $row .= '<td>';
255  // Hide deleted usernames
256  if ( $file->isDeleted( File::DELETED_USER ) ) {
257  $row .= '<span class="history-deleted">'
258  . $this->msg( 'rev-deleted-user' )->escaped() . '</span>';
259  } else {
260  if ( $local ) {
261  $row .= Linker::userLink( $userId, $userText );
262  $row .= '<span style="white-space: nowrap;">';
263  $row .= Linker::userToolLinks( $userId, $userText );
264  $row .= '</span>';
265  } else {
266  $row .= htmlspecialchars( $userText );
267  }
268  }
269  $row .= '</td>';
270 
271  // Don't show deleted descriptions
272  if ( $file->isDeleted( File::DELETED_COMMENT ) ) {
273  $row .= '<td><span class="history-deleted">' .
274  $this->msg( 'rev-deleted-comment' )->escaped() . '</span></td>';
275  } else {
276  $contLang = MediaWikiServices::getInstance()->getContentLanguage();
277  $row .= Html::rawElement(
278  'td',
279  [ 'dir' => $contLang->getDir() ],
280  Linker::formatComment( $description, $this->title )
281  );
282  }
283 
284  $rowClass = null;
285  $this->getHookRunner()->onImagePageFileHistoryLine( $this, $file, $row, $rowClass );
286  $classAttr = $rowClass ? " class='$rowClass'" : '';
287 
288  return "<tr{$classAttr}>{$row}</tr>\n";
289  }
290 
295  protected function getThumbForLine( $file ) {
296  $lang = $this->getLanguage();
297  $user = $this->getUser();
298  if ( $file->allowInlineDisplay() && $file->userCan( File::DELETED_FILE, $user )
299  && !$file->isDeleted( File::DELETED_FILE )
300  ) {
301  $params = [
302  'width' => '120',
303  'height' => '120',
304  ];
305  $timestamp = wfTimestamp( TS_MW, $file->getTimestamp() );
306 
307  $thumbnail = $file->transform( $params );
308  $options = [
309  'alt' => $this->msg( 'filehist-thumbtext',
310  $lang->userTimeAndDate( $timestamp, $user ),
311  $lang->userDate( $timestamp, $user ),
312  $lang->userTime( $timestamp, $user ) )->text(),
313  'file-link' => true,
314  ];
315 
316  if ( !$thumbnail ) {
317  return $this->msg( 'filehist-nothumb' )->escaped();
318  }
319 
320  return $thumbnail->toHtml( $options );
321  } else {
322  return $this->msg( 'filehist-nothumb' )->escaped();
323  }
324  }
325 
329  protected function preventClickjacking( $enable = true ) {
330  $this->preventClickjacking = $enable;
331  }
332 
336  public function getPreventClickjacking() {
338  }
339 }
ContextSource\$context
IContextSource $context
Definition: ContextSource.php:38
File\DELETED_USER
const DELETED_USER
Definition: File.php:69
ImageHistoryList\$img
File $img
Definition: ImageHistoryList.php:40
ImageHistoryList
Builds the image revision log shown on image pages.
Definition: ImageHistoryList.php:29
Linker\userLink
static userLink( $userId, $userName, $altUserName=false)
Make user link (or user contributions for unregistered users)
Definition: Linker.php:897
File\DELETED_RESTRICTED
const DELETED_RESTRICTED
Definition: File.php:70
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:173
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
ImageHistoryList\$showThumb
$showThumb
Definition: ImageHistoryList.php:52
ImageHistoryList\imageHistoryLine
imageHistoryLine( $iscur, $file)
Definition: ImageHistoryList.php:118
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:1832
Linker\userToolLinks
static userToolLinks( $userId, $userText, $redContribsWhenNoEdits=false, $flags=0, $edits=null, $useParentheses=true)
Generate standard user tool links (talk, contributions, block link, etc.)
Definition: Linker.php:942
ImageHistoryList\__construct
__construct( $imagePage)
Definition: ImageHistoryList.php:58
$file
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42
SpecialPage\getTitleFor
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
Definition: SpecialPage.php:107
ImagePage
Class for viewing MediaWiki file description pages.
Definition: ImagePage.php:33
ContextSource\getUser
getUser()
Definition: ContextSource.php:135
Xml\openElement
static openElement( $element, $attribs=null)
This opens an XML element.
Definition: Xml.php:110
ContextSource\getLanguage
getLanguage()
Definition: ContextSource.php:151
ImageHistoryList\getImagePage
getImagePage()
Definition: ImageHistoryList.php:72
File
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition: File.php:63
File\DELETED_COMMENT
const DELETED_COMMENT
Definition: File.php:68
Article\getTitle
getTitle()
Get the title object of the article.
Definition: Article.php:213
ImageHistoryList\$repo
$repo
Definition: ImageHistoryList.php:52
ContextSource
The simplest way of implementing IContextSource is to hold a RequestContext as a member variable and ...
Definition: ContextSource.php:32
Xml\element
static element( $element, $attribs=null, $contents='', $allowShortTag=true)
Format an XML element with given attributes and, optionally, text content.
Definition: Xml.php:41
Article\getPage
getPage()
Get the WikiPage object of this instance.
Definition: Article.php:223
Article\getContext
getContext()
Gets the context this Article is executed in.
Definition: Article.php:2324
Linker\revDeleteLinkDisabled
static revDeleteLinkDisabled( $delete=true)
Creates a dead (show/hide) link for deleting revisions/log entries.
Definition: Linker.php:2265
File\FOR_THIS_USER
const FOR_THIS_USER
Definition: File.php:84
ContextSource\setContext
setContext(IContextSource $context)
Definition: ContextSource.php:62
ImageHistoryList\preventClickjacking
preventClickjacking( $enable=true)
Definition: ImageHistoryList.php:329
ImageHistoryList\$imagePage
ImagePage $imagePage
Definition: ImageHistoryList.php:45
ImageHistoryList\getFile
getFile()
Definition: ImageHistoryList.php:79
ContextSource\msg
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Definition: ContextSource.php:195
ContextSource\getAuthority
getAuthority()
Definition: ContextSource.php:142
ImagePage\getDisplayedFile
getDisplayedFile()
Definition: ImagePage.php:223
Linker\formatComment
static formatComment( $comment, $title=null, $local=false, $wikiId=null)
This function is called by all recent changes variants, by the page history, and by the user contribu...
Definition: Linker.php:1191
Title
Represents a title within MediaWiki.
Definition: Title.php:46
ImageHistoryList\$title
Title $title
Definition: ImageHistoryList.php:35
ImageHistoryList\getThumbForLine
getThumbForLine( $file)
Definition: ImageHistoryList.php:295
IContextSource\getConfig
getConfig()
Get the site configuration.
Html\rawElement
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:212
Linker\revDeleteLink
static revDeleteLink( $query=[], $restricted=false, $delete=true)
Creates a (show/hide) link for deleting revisions/log entries.
Definition: Linker.php:2243
ImageHistoryList\beginImageHistoryList
beginImageHistoryList( $navLinks='')
Definition: ImageHistoryList.php:87
File\DELETED_FILE
const DELETED_FILE
Definition: File.php:67
Html\element
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:234
ImageHistoryList\$preventClickjacking
$preventClickjacking
Definition: ImageHistoryList.php:53
ImageHistoryList\$current
File $current
Definition: ImageHistoryList.php:50
ImageHistoryList\getPreventClickjacking
getPreventClickjacking()
Definition: ImageHistoryList.php:336
ImageHistoryList\endImageHistoryList
endImageHistoryList( $navLinks='')
Definition: ImageHistoryList.php:109