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  && ( MediaWikiServices::getInstance()
97  ->getPermissionManager()
98  ->userHasAnyRight( $this->getUser(), 'delete', 'deletedhistory' ) ) ? '<th></th>' : '' )
99  . '<th>' . $this->msg( 'filehist-datetime' )->escaped() . '</th>'
100  . ( $this->showThumb ? '<th>' . $this->msg( 'filehist-thumb' )->escaped() . '</th>' : '' )
101  . '<th>' . $this->msg( 'filehist-dimensions' )->escaped() . '</th>'
102  . '<th>' . $this->msg( 'filehist-user' )->escaped() . '</th>'
103  . '<th>' . $this->msg( 'filehist-comment' )->escaped() . '</th>'
104  . "</tr>\n";
105  }
106 
111  public function endImageHistoryList( $navLinks = '' ) {
112  return "</table>\n$navLinks\n</div>\n";
113  }
114 
120  public function imageHistoryLine( $iscur, $file ) {
121  $user = $this->getUser();
122  $lang = $this->getLanguage();
123  $pm = MediaWikiServices::getInstance()->getPermissionManager();
124  $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
125  $timestamp = wfTimestamp( TS_MW, $file->getTimestamp() );
126  // @phan-suppress-next-line PhanUndeclaredMethod
127  $img = $iscur ? $file->getName() : $file->getArchiveName();
128  $userId = $file->getUser( 'id' );
129  $userText = $file->getUser( 'text' );
130  $description = $file->getDescription( File::FOR_THIS_USER, $user );
131 
132  $local = $this->current->isLocal();
133  $row = $selected = '';
134 
135  // Deletion link
136  if ( $local && ( $pm->userHasAnyRight( $user, 'delete', 'deletedhistory' ) ) ) {
137  $row .= '<td>';
138  # Link to remove from history
139  if ( $pm->userHasRight( $user, 'delete' ) ) {
140  $q = [ 'action' => 'delete' ];
141  if ( !$iscur ) {
142  $q['oldimage'] = $img;
143  }
144  $row .= $linkRenderer->makeKnownLink(
145  $this->title,
146  $this->msg( $iscur ? 'filehist-deleteall' : 'filehist-deleteone' )->text(),
147  [], $q
148  );
149  }
150  # Link to hide content. Don't show useless link to people who cannot hide revisions.
151  $canHide = $pm->userHasRight( $user, 'deleterevision' );
152  if ( $canHide || ( $pm->userHasRight( $user, 'deletedhistory' )
153  && $file->getVisibility() ) ) {
154  if ( $pm->userHasRight( $user, 'delete' ) ) {
155  $row .= '<br />';
156  }
157  // If file is top revision or locked from this user, don't link
158  if ( $iscur || !$file->userCan( File::DELETED_RESTRICTED, $user ) ) {
159  $del = Linker::revDeleteLinkDisabled( $canHide );
160  } else {
161  list( $ts, ) = explode( '!', $img, 2 );
162  $query = [
163  'type' => 'oldimage',
164  'target' => $this->title->getPrefixedText(),
165  'ids' => $ts,
166  ];
167  $del = Linker::revDeleteLink( $query,
168  $file->isDeleted( File::DELETED_RESTRICTED ), $canHide );
169  }
170  $row .= $del;
171  }
172  $row .= '</td>';
173  }
174 
175  // Reversion link/current indicator
176  $row .= '<td>';
177  if ( $iscur ) {
178  $row .= $this->msg( 'filehist-current' )->escaped();
179  } elseif ( $local && $pm->quickUserCan( 'edit', $user, $this->title )
180  && $pm->quickUserCan( 'upload', $user, $this->title )
181  ) {
182  if ( $file->isDeleted( File::DELETED_FILE ) ) {
183  $row .= $this->msg( 'filehist-revert' )->escaped();
184  } else {
185  $row .= $linkRenderer->makeKnownLink(
186  $this->title,
187  $this->msg( 'filehist-revert' )->text(),
188  [],
189  [
190  'action' => 'revert',
191  'oldimage' => $img,
192  ]
193  );
194  }
195  }
196  $row .= '</td>';
197 
198  // Date/time and image link
199  if ( $file->getTimestamp() === $this->img->getTimestamp() ) {
200  $selected = "class='filehistory-selected'";
201  }
202  $row .= "<td $selected style='white-space: nowrap;'>";
203  if ( !$file->userCan( File::DELETED_FILE, $user ) ) {
204  # Don't link to unviewable files
205  $row .= Html::element( 'span', [ 'class' => 'history-deleted' ],
206  $lang->userTimeAndDate( $timestamp, $user )
207  );
208  } elseif ( $file->isDeleted( File::DELETED_FILE ) ) {
209  $timeAndDate = $lang->userTimeAndDate( $timestamp, $user );
210  if ( $local ) {
211  $this->preventClickjacking();
212  $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
213  # Make a link to review the image
214  $url = $linkRenderer->makeKnownLink(
215  $revdel,
216  $timeAndDate,
217  [],
218  [
219  'target' => $this->title->getPrefixedText(),
220  'file' => $img,
221  'token' => $user->getEditToken( $img )
222  ]
223  );
224  } else {
225  $url = htmlspecialchars( $timeAndDate );
226  }
227  $row .= '<span class="history-deleted">' . $url . '</span>';
228  } elseif ( !$file->exists() ) {
229  $row .= Html::element( 'span', [ 'class' => 'mw-file-missing' ],
230  $lang->userTimeAndDate( $timestamp, $user )
231  );
232  } else {
233  $url = $iscur ? $this->current->getUrl() : $this->current->getArchiveUrl( $img );
234  $row .= Xml::element(
235  'a',
236  [ 'href' => $url ],
237  $lang->userTimeAndDate( $timestamp, $user )
238  );
239  }
240  $row .= "</td>";
241 
242  // Thumbnail
243  if ( $this->showThumb ) {
244  $row .= '<td>' . $this->getThumbForLine( $file ) . '</td>';
245  }
246 
247  // Image dimensions + size
248  $row .= '<td>';
249  $row .= htmlspecialchars( $file->getDimensionsString() );
250  $row .= $this->msg( 'word-separator' )->escaped();
251  $row .= '<span style="white-space: nowrap;">';
252  $row .= $this->msg( 'parentheses' )->sizeParams( $file->getSize() )->escaped();
253  $row .= '</span>';
254  $row .= '</td>';
255 
256  // Uploading user
257  $row .= '<td>';
258  // Hide deleted usernames
259  if ( $file->isDeleted( File::DELETED_USER ) ) {
260  $row .= '<span class="history-deleted">'
261  . $this->msg( 'rev-deleted-user' )->escaped() . '</span>';
262  } else {
263  if ( $local ) {
264  $row .= Linker::userLink( $userId, $userText );
265  $row .= '<span style="white-space: nowrap;">';
266  $row .= Linker::userToolLinks( $userId, $userText );
267  $row .= '</span>';
268  } else {
269  $row .= htmlspecialchars( $userText );
270  }
271  }
272  $row .= '</td>';
273 
274  // Don't show deleted descriptions
275  if ( $file->isDeleted( File::DELETED_COMMENT ) ) {
276  $row .= '<td><span class="history-deleted">' .
277  $this->msg( 'rev-deleted-comment' )->escaped() . '</span></td>';
278  } else {
279  $contLang = MediaWikiServices::getInstance()->getContentLanguage();
280  $row .= Html::rawElement(
281  'td',
282  [ 'dir' => $contLang->getDir() ],
283  Linker::formatComment( $description, $this->title )
284  );
285  }
286 
287  $rowClass = null;
288  $this->getHookRunner()->onImagePageFileHistoryLine( $this, $file, $row, $rowClass );
289  $classAttr = $rowClass ? " class='$rowClass'" : '';
290 
291  return "<tr{$classAttr}>{$row}</tr>\n";
292  }
293 
298  protected function getThumbForLine( $file ) {
299  $lang = $this->getLanguage();
300  $user = $this->getUser();
301  if ( $file->allowInlineDisplay() && $file->userCan( File::DELETED_FILE, $user )
302  && !$file->isDeleted( File::DELETED_FILE )
303  ) {
304  $params = [
305  'width' => '120',
306  'height' => '120',
307  ];
308  $timestamp = wfTimestamp( TS_MW, $file->getTimestamp() );
309 
310  $thumbnail = $file->transform( $params );
311  $options = [
312  'alt' => $this->msg( 'filehist-thumbtext',
313  $lang->userTimeAndDate( $timestamp, $user ),
314  $lang->userDate( $timestamp, $user ),
315  $lang->userTime( $timestamp, $user ) )->text(),
316  'file-link' => true,
317  ];
318 
319  if ( !$thumbnail ) {
320  return $this->msg( 'filehist-nothumb' )->escaped();
321  }
322 
323  return $thumbnail->toHtml( $options );
324  } else {
325  return $this->msg( 'filehist-nothumb' )->escaped();
326  }
327  }
328 
332  protected function preventClickjacking( $enable = true ) {
333  $this->preventClickjacking = $enable;
334  }
335 
339  public function getPreventClickjacking() {
341  }
342 }
ContextSource\$context
IContextSource $context
Definition: ContextSource.php:34
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:896
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:154
$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:120
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:1808
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:941
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:92
ImagePage
Class for viewing MediaWiki file description pages.
Definition: ImagePage.php:33
ContextSource\getUser
getUser()
Stable to override.
Definition: ContextSource.php:131
Xml\openElement
static openElement( $element, $attribs=null)
This opens an XML element.
Definition: Xml.php:108
ContextSource\getLanguage
getLanguage()
Definition: ContextSource.php:140
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:255
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:30
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:265
Article\getContext
getContext()
Gets the context this Article is executed in.
Definition: Article.php:2336
Linker\revDeleteLinkDisabled
static revDeleteLinkDisabled( $delete=true)
Creates a dead (show/hide) link for deleting revisions/log entries.
Definition: Linker.php:2275
File\FOR_THIS_USER
const FOR_THIS_USER
Definition: File.php:84
ContextSource\setContext
setContext(IContextSource $context)
Definition: ContextSource.php:58
ImageHistoryList\preventClickjacking
preventClickjacking( $enable=true)
Definition: ImageHistoryList.php:332
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:184
ImagePage\getDisplayedFile
getDisplayedFile()
Definition: ImagePage.php:225
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:1199
Title
Represents a title within MediaWiki.
Definition: Title.php:42
ImageHistoryList\$title
Title $title
Definition: ImageHistoryList.php:35
ImageHistoryList\getThumbForLine
getThumbForLine( $file)
Definition: ImageHistoryList.php:298
IContextSource\getConfig
getConfig()
Get the site configuration.
Html\rawElement
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:209
Linker\revDeleteLink
static revDeleteLink( $query=[], $restricted=false, $delete=true)
Creates a (show/hide) link for deleting revisions/log entries.
Definition: Linker.php:2253
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:231
ImageHistoryList\$preventClickjacking
$preventClickjacking
Definition: ImageHistoryList.php:53
ImageHistoryList\$current
File $current
Definition: ImageHistoryList.php:50
ImageHistoryList\getPreventClickjacking
getPreventClickjacking()
Definition: ImageHistoryList.php:339
ImageHistoryList\endImageHistoryList
endImageHistoryList( $navLinks='')
Definition: ImageHistoryList.php:111