MediaWiki  1.29.2
ImagePage.php
Go to the documentation of this file.
1 <?php
24 
30 class ImagePage extends Article {
32  private $displayImg;
33 
35  private $repo;
36 
38  private $fileLoaded;
39 
41  protected $mExtraDescription = false;
42 
46  protected $mPage;
47 
52  protected function newPage( Title $title ) {
53  // Overload mPage with a file-specific page
54  return new WikiFilePage( $title );
55  }
56 
61  public function setFile( $file ) {
62  $this->mPage->setFile( $file );
63  $this->displayImg = $file;
64  $this->fileLoaded = true;
65  }
66 
67  protected function loadFile() {
68  if ( $this->fileLoaded ) {
69  return;
70  }
71  $this->fileLoaded = true;
72 
73  $this->displayImg = $img = false;
74 
75  Hooks::run( 'ImagePageFindFile', [ $this, &$img, &$this->displayImg ] );
76  if ( !$img ) { // not set by hook?
77  $img = wfFindFile( $this->getTitle() );
78  if ( !$img ) {
79  $img = wfLocalFile( $this->getTitle() );
80  }
81  }
82  $this->mPage->setFile( $img );
83  if ( !$this->displayImg ) { // not set by hook?
84  $this->displayImg = $img;
85  }
86  $this->repo = $img->getRepo();
87  }
88 
93  public function render() {
94  $this->getContext()->getOutput()->setArticleBodyOnly( true );
95  parent::view();
96  }
97 
98  public function view() {
100 
101  $out = $this->getContext()->getOutput();
102  $request = $this->getContext()->getRequest();
103  $diff = $request->getVal( 'diff' );
104  $diffOnly = $request->getBool(
105  'diffonly',
106  $this->getContext()->getUser()->getOption( 'diffonly' )
107  );
108 
109  if ( $this->getTitle()->getNamespace() != NS_FILE || ( $diff !== null && $diffOnly ) ) {
110  parent::view();
111  return;
112  }
113 
114  $this->loadFile();
115 
116  if ( $this->getTitle()->getNamespace() == NS_FILE && $this->mPage->getFile()->getRedirected() ) {
117  if ( $this->getTitle()->getDBkey() == $this->mPage->getFile()->getName() || $diff !== null ) {
118  // mTitle is the same as the redirect target so ask Article
119  // to perform the redirect for us.
120  $request->setVal( 'diffonly', 'true' );
121  parent::view();
122  return;
123  } else {
124  // mTitle is not the same as the redirect target so it is
125  // probably the redirect page itself. Fake the redirect symbol
126  $out->setPageTitle( $this->getTitle()->getPrefixedText() );
127  $out->addHTML( $this->viewRedirect(
128  Title::makeTitle( NS_FILE, $this->mPage->getFile()->getName() ),
129  /* $appendSubtitle */ true,
130  /* $forceKnown */ true )
131  );
132  $this->mPage->doViewUpdates( $this->getContext()->getUser(), $this->getOldID() );
133  return;
134  }
135  }
136 
137  if ( $wgShowEXIF && $this->displayImg->exists() ) {
138  // @todo FIXME: Bad interface, see note on MediaHandler::formatMetadata().
139  $formattedMetadata = $this->displayImg->formatMetadata( $this->getContext() );
140  $showmeta = $formattedMetadata !== false;
141  } else {
142  $showmeta = false;
143  }
144 
145  if ( !$diff && $this->displayImg->exists() ) {
146  $out->addHTML( $this->showTOC( $showmeta ) );
147  }
148 
149  if ( !$diff ) {
150  $this->openShowImage();
151  }
152 
153  # No need to display noarticletext, we use our own message, output in openShowImage()
154  if ( $this->mPage->getId() ) {
155  # NS_FILE is in the user language, but this section (the actual wikitext)
156  # should be in page content language
157  $pageLang = $this->getTitle()->getPageViewLanguage();
158  $out->addHTML( Xml::openElement( 'div', [ 'id' => 'mw-imagepage-content',
159  'lang' => $pageLang->getHtmlCode(), 'dir' => $pageLang->getDir(),
160  'class' => 'mw-content-' . $pageLang->getDir() ] ) );
161 
162  parent::view();
163 
164  $out->addHTML( Xml::closeElement( 'div' ) );
165  } else {
166  # Just need to set the right headers
167  $out->setArticleFlag( true );
168  $out->setPageTitle( $this->getTitle()->getPrefixedText() );
169  $this->mPage->doViewUpdates( $this->getContext()->getUser(), $this->getOldID() );
170  }
171 
172  # Show shared description, if needed
173  if ( $this->mExtraDescription ) {
174  $fol = $this->getContext()->msg( 'shareddescriptionfollows' );
175  if ( !$fol->isDisabled() ) {
176  $out->addWikiText( $fol->plain() );
177  }
178  $out->addHTML( '<div id="shared-image-desc">' . $this->mExtraDescription . "</div>\n" );
179  }
180 
181  $this->closeShowImage();
182  $this->imageHistory();
183  // TODO: Cleanup the following
184 
185  $out->addHTML( Xml::element( 'h2',
186  [ 'id' => 'filelinks' ],
187  $this->getContext()->msg( 'imagelinks' )->text() ) . "\n" );
188  $this->imageDupes();
189  # @todo FIXME: For some freaky reason, we can't redirect to foreign images.
190  # Yet we return metadata about the target. Definitely an issue in the FileRepo
191  $this->imageLinks();
192 
193  # Allow extensions to add something after the image links
194  $html = '';
195  Hooks::run( 'ImagePageAfterImageLinks', [ $this, &$html ] );
196  if ( $html ) {
197  $out->addHTML( $html );
198  }
199 
200  if ( $showmeta ) {
201  $out->addHTML( Xml::element(
202  'h2',
203  [ 'id' => 'metadata' ],
204  $this->getContext()->msg( 'metadata' )->text() ) . "\n" );
205  $out->addWikiText( $this->makeMetadataTable( $formattedMetadata ) );
206  $out->addModules( [ 'mediawiki.action.view.metadata' ] );
207  }
208 
209  // Add remote Filepage.css
210  if ( !$this->repo->isLocal() ) {
211  $css = $this->repo->getDescriptionStylesheetUrl();
212  if ( $css ) {
213  $out->addStyle( $css );
214  }
215  }
216 
217  $out->addModuleStyles( [
218  'filepage', // always show the local local Filepage.css, T31277
219  'mediawiki.action.view.filepage', // Add MediaWiki styles for a file page
220  ] );
221  }
222 
226  public function getDisplayedFile() {
227  $this->loadFile();
228  return $this->displayImg;
229  }
230 
237  protected function showTOC( $metadata ) {
238  $r = [
239  '<li><a href="#file">' . $this->getContext()->msg( 'file-anchor-link' )->escaped() . '</a></li>',
240  '<li><a href="#filehistory">' . $this->getContext()->msg( 'filehist' )->escaped() . '</a></li>',
241  '<li><a href="#filelinks">' . $this->getContext()->msg( 'imagelinks' )->escaped() . '</a></li>',
242  ];
243 
244  Hooks::run( 'ImagePageShowTOC', [ $this, &$r ] );
245 
246  if ( $metadata ) {
247  $r[] = '<li><a href="#metadata">' .
248  $this->getContext()->msg( 'metadata' )->escaped() .
249  '</a></li>';
250  }
251 
252  return '<ul id="filetoc">' . implode( "\n", $r ) . '</ul>';
253  }
254 
263  protected function makeMetadataTable( $metadata ) {
264  $r = "<div class=\"mw-imagepage-section-metadata\">";
265  $r .= $this->getContext()->msg( 'metadata-help' )->plain();
266  $r .= "<table id=\"mw_metadata\" class=\"mw_metadata\">\n";
267  foreach ( $metadata as $type => $stuff ) {
268  foreach ( $stuff as $v ) {
269  # @todo FIXME: Why is this using escapeId for a class?!
270  $class = Sanitizer::escapeId( $v['id'] );
271  if ( $type == 'collapsed' ) {
272  // Handled by mediawiki.action.view.metadata module.
273  $class .= ' collapsable';
274  }
275  $r .= "<tr class=\"$class\">\n";
276  $r .= "<th>{$v['name']}</th>\n";
277  $r .= "<td>{$v['value']}</td>\n</tr>";
278  }
279  }
280  $r .= "</table>\n</div>\n";
281  return $r;
282  }
283 
291  public function getContentObject() {
292  $this->loadFile();
293  if ( $this->mPage->getFile() && !$this->mPage->getFile()->isLocal() && 0 == $this->getId() ) {
294  return null;
295  }
296  return parent::getContentObject();
297  }
298 
299  protected function openShowImage() {
300  global $wgEnableUploads, $wgSend404Code, $wgSVGMaxSize;
301 
302  $this->loadFile();
303  $out = $this->getContext()->getOutput();
304  $user = $this->getContext()->getUser();
305  $lang = $this->getContext()->getLanguage();
306  $dirmark = $lang->getDirMarkEntity();
307  $request = $this->getContext()->getRequest();
308 
309  $max = $this->getImageLimitsFromOption( $user, 'imagesize' );
310  $maxWidth = $max[0];
311  $maxHeight = $max[1];
312 
313  if ( $this->displayImg->exists() ) {
314  # image
315  $page = $request->getIntOrNull( 'page' );
316  if ( is_null( $page ) ) {
317  $params = [];
318  $page = 1;
319  } else {
320  $params = [ 'page' => $page ];
321  }
322 
323  $renderLang = $request->getVal( 'lang' );
324  if ( !is_null( $renderLang ) ) {
325  $handler = $this->displayImg->getHandler();
326  if ( $handler && $handler->validateParam( 'lang', $renderLang ) ) {
327  $params['lang'] = $renderLang;
328  } else {
329  $renderLang = null;
330  }
331  }
332 
333  $width_orig = $this->displayImg->getWidth( $page );
334  $width = $width_orig;
335  $height_orig = $this->displayImg->getHeight( $page );
336  $height = $height_orig;
337 
338  $filename = wfEscapeWikiText( $this->displayImg->getName() );
339  $linktext = $filename;
340 
341  // Avoid PHP 7.1 warning from passing $this by reference
342  $imagePage = $this;
343 
344  Hooks::run( 'ImageOpenShowImageInlineBefore', [ &$imagePage, &$out ] );
345 
346  if ( $this->displayImg->allowInlineDisplay() ) {
347  # image
348  # "Download high res version" link below the image
349  # $msgsize = $this->getContext()->msg( 'file-info-size', $width_orig, $height_orig,
350  # Linker::formatSize( $this->displayImg->getSize() ), $mime )->escaped();
351  # We'll show a thumbnail of this image
352  if ( $width > $maxWidth || $height > $maxHeight || $this->displayImg->isVectorized() ) {
353  list( $width, $height ) = $this->getDisplayWidthHeight(
354  $maxWidth, $maxHeight, $width, $height
355  );
356  $linktext = $this->getContext()->msg( 'show-big-image' )->escaped();
357 
358  $thumbSizes = $this->getThumbSizes( $width_orig, $height_orig );
359  # Generate thumbnails or thumbnail links as needed...
360  $otherSizes = [];
361  foreach ( $thumbSizes as $size ) {
362  // We include a thumbnail size in the list, if it is
363  // less than or equal to the original size of the image
364  // asset ($width_orig/$height_orig). We also exclude
365  // the current thumbnail's size ($width/$height)
366  // since that is added to the message separately, so
367  // it can be denoted as the current size being shown.
368  // Vectorized images are limited by $wgSVGMaxSize big,
369  // so all thumbs less than or equal that are shown.
370  if ( ( ( $size[0] <= $width_orig && $size[1] <= $height_orig )
371  || ( $this->displayImg->isVectorized()
372  && max( $size[0], $size[1] ) <= $wgSVGMaxSize )
373  )
374  && $size[0] != $width && $size[1] != $height
375  ) {
376  $sizeLink = $this->makeSizeLink( $params, $size[0], $size[1] );
377  if ( $sizeLink ) {
378  $otherSizes[] = $sizeLink;
379  }
380  }
381  }
382  $otherSizes = array_unique( $otherSizes );
383 
384  $sizeLinkBigImagePreview = $this->makeSizeLink( $params, $width, $height );
385  $msgsmall = $this->getThumbPrevText( $params, $sizeLinkBigImagePreview );
386  if ( count( $otherSizes ) ) {
387  $msgsmall .= ' ' .
389  'span',
390  [ 'class' => 'mw-filepage-other-resolutions' ],
391  $this->getContext()->msg( 'show-big-image-other' )
392  ->rawParams( $lang->pipeList( $otherSizes ) )
393  ->params( count( $otherSizes ) )
394  ->parse()
395  );
396  }
397  } elseif ( $width == 0 && $height == 0 ) {
398  # Some sort of audio file that doesn't have dimensions
399  # Don't output a no hi res message for such a file
400  $msgsmall = '';
401  } else {
402  # Image is small enough to show full size on image page
403  $msgsmall = $this->getContext()->msg( 'file-nohires' )->parse();
404  }
405 
406  $params['width'] = $width;
407  $params['height'] = $height;
408  $thumbnail = $this->displayImg->transform( $params );
409  Linker::processResponsiveImages( $this->displayImg, $thumbnail, $params );
410 
411  $anchorclose = Html::rawElement(
412  'div',
413  [ 'class' => 'mw-filepage-resolutioninfo' ],
414  $msgsmall
415  );
416 
417  $isMulti = $this->displayImg->isMultipage() && $this->displayImg->pageCount() > 1;
418  if ( $isMulti ) {
419  $out->addModules( 'mediawiki.page.image.pagination' );
420  $out->addHTML( '<table class="multipageimage"><tr><td>' );
421  }
422 
423  if ( $thumbnail ) {
424  $options = [
425  'alt' => $this->displayImg->getTitle()->getPrefixedText(),
426  'file-link' => true,
427  ];
428  $out->addHTML( '<div class="fullImageLink" id="file">' .
429  $thumbnail->toHtml( $options ) .
430  $anchorclose . "</div>\n" );
431  }
432 
433  if ( $isMulti ) {
434  $count = $this->displayImg->pageCount();
435 
436  if ( $page > 1 ) {
437  $label = $out->parse( $this->getContext()->msg( 'imgmultipageprev' )->text(), false );
438  // on the client side, this link is generated in ajaxifyPageNavigation()
439  // in the mediawiki.page.image.pagination module
441  $this->getTitle(),
442  $label,
443  [],
444  [ 'page' => $page - 1 ]
445  );
446  $thumb1 = Linker::makeThumbLinkObj(
447  $this->getTitle(),
448  $this->displayImg,
449  $link,
450  $label,
451  'none',
452  [ 'page' => $page - 1 ]
453  );
454  } else {
455  $thumb1 = '';
456  }
457 
458  if ( $page < $count ) {
459  $label = $this->getContext()->msg( 'imgmultipagenext' )->text();
461  $this->getTitle(),
462  $label,
463  [],
464  [ 'page' => $page + 1 ]
465  );
466  $thumb2 = Linker::makeThumbLinkObj(
467  $this->getTitle(),
468  $this->displayImg,
469  $link,
470  $label,
471  'none',
472  [ 'page' => $page + 1 ]
473  );
474  } else {
475  $thumb2 = '';
476  }
477 
479 
480  $formParams = [
481  'name' => 'pageselector',
482  'action' => $wgScript,
483  ];
484  $options = [];
485  for ( $i = 1; $i <= $count; $i++ ) {
486  $options[] = Xml::option( $lang->formatNum( $i ), $i, $i == $page );
487  }
488  $select = Xml::tags( 'select',
489  [ 'id' => 'pageselector', 'name' => 'page' ],
490  implode( "\n", $options ) );
491 
492  $out->addHTML(
493  '</td><td><div class="multipageimagenavbox">' .
494  Xml::openElement( 'form', $formParams ) .
495  Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() ) .
496  $this->getContext()->msg( 'imgmultigoto' )->rawParams( $select )->parse() .
497  Xml::submitButton( $this->getContext()->msg( 'imgmultigo' )->text() ) .
498  Xml::closeElement( 'form' ) .
499  "<hr />$thumb1\n$thumb2<br style=\"clear: both\" /></div></td></tr></table>"
500  );
501  }
502  } elseif ( $this->displayImg->isSafeFile() ) {
503  # if direct link is allowed but it's not a renderable image, show an icon.
504  $icon = $this->displayImg->iconThumb();
505 
506  $out->addHTML( '<div class="fullImageLink" id="file">' .
507  $icon->toHtml( [ 'file-link' => true ] ) .
508  "</div>\n" );
509  }
510 
511  $longDesc = $this->getContext()->msg( 'parentheses', $this->displayImg->getLongDesc() )->text();
512 
513  $handler = $this->displayImg->getHandler();
514 
515  // If this is a filetype with potential issues, warn the user.
516  if ( $handler ) {
517  $warningConfig = $handler->getWarningConfig( $this->displayImg );
518 
519  if ( $warningConfig !== null ) {
520  // The warning will be displayed via CSS and JavaScript.
521  // We just need to tell the client side what message to use.
522  $output = $this->getContext()->getOutput();
523  $output->addJsConfigVars( 'wgFileWarning', $warningConfig );
524  $output->addModules( $warningConfig['module'] );
525  $output->addModules( 'mediawiki.filewarning' );
526  }
527  }
528 
529  $medialink = "[[Media:$filename|$linktext]]";
530 
531  if ( !$this->displayImg->isSafeFile() ) {
532  $warning = $this->getContext()->msg( 'mediawarning' )->plain();
533  // dirmark is needed here to separate the file name, which
534  // most likely ends in Latin characters, from the description,
535  // which may begin with the file type. In RTL environment
536  // this will get messy.
537  // The dirmark, however, must not be immediately adjacent
538  // to the filename, because it can get copied with it.
539  // See T27277.
540  // @codingStandardsIgnoreStart Ignore long line
541  $out->addWikiText( <<<EOT
542 <div class="fullMedia"><span class="dangerousLink">{$medialink}</span> $dirmark<span class="fileInfo">$longDesc</span></div>
543 <div class="mediaWarning">$warning</div>
544 EOT
545  );
546  // @codingStandardsIgnoreEnd
547  } else {
548  $out->addWikiText( <<<EOT
549 <div class="fullMedia">{$medialink} {$dirmark}<span class="fileInfo">$longDesc</span>
550 </div>
551 EOT
552  );
553  }
554 
555  $renderLangOptions = $this->displayImg->getAvailableLanguages();
556  if ( count( $renderLangOptions ) >= 1 ) {
557  $currentLanguage = $renderLang;
558  $defaultLang = $this->displayImg->getDefaultRenderLanguage();
559  if ( is_null( $currentLanguage ) ) {
560  $currentLanguage = $defaultLang;
561  }
562  $out->addHTML( $this->doRenderLangOpt( $renderLangOptions, $currentLanguage, $defaultLang ) );
563  }
564 
565  // Add cannot animate thumbnail warning
566  if ( !$this->displayImg->canAnimateThumbIfAppropriate() ) {
567  // Include the extension so wiki admins can
568  // customize it on a per file-type basis
569  // (aka say things like use format X instead).
570  // additionally have a specific message for
571  // file-no-thumb-animation-gif
572  $ext = $this->displayImg->getExtension();
573  $noAnimMesg = wfMessageFallback(
574  'file-no-thumb-animation-' . $ext,
575  'file-no-thumb-animation'
576  )->plain();
577 
578  $out->addWikiText( <<<EOT
579 <div class="mw-noanimatethumb">{$noAnimMesg}</div>
580 EOT
581  );
582  }
583 
584  if ( !$this->displayImg->isLocal() ) {
585  $this->printSharedImageText();
586  }
587  } else {
588  # Image does not exist
589  if ( !$this->getId() ) {
590  $dbr = wfGetDB( DB_REPLICA );
591 
592  # No article exists either
593  # Show deletion log to be consistent with normal articles
595  $out,
596  [ 'delete', 'move' ],
597  $this->getTitle()->getPrefixedText(),
598  '',
599  [ 'lim' => 10,
600  'conds' => [ 'log_action != ' . $dbr->addQuotes( 'revision' ) ],
601  'showIfEmpty' => false,
602  'msgKey' => [ 'moveddeleted-notice' ]
603  ]
604  );
605  }
606 
607  if ( $wgEnableUploads && $user->isAllowed( 'upload' ) ) {
608  // Only show an upload link if the user can upload
609  $uploadTitle = SpecialPage::getTitleFor( 'Upload' );
610  $nofile = [
611  'filepage-nofile-link',
612  $uploadTitle->getFullURL( [ 'wpDestFile' => $this->mPage->getFile()->getName() ] )
613  ];
614  } else {
615  $nofile = 'filepage-nofile';
616  }
617  // Note, if there is an image description page, but
618  // no image, then this setRobotPolicy is overridden
619  // by Article::View().
620  $out->setRobotPolicy( 'noindex,nofollow' );
621  $out->wrapWikiMsg( "<div id='mw-imagepage-nofile' class='plainlinks'>\n$1\n</div>", $nofile );
622  if ( !$this->getId() && $wgSend404Code ) {
623  // If there is no image, no shared image, and no description page,
624  // output a 404, to be consistent with Article::showMissingArticle.
625  $request->response()->statusHeader( 404 );
626  }
627  }
628  $out->setFileVersion( $this->displayImg );
629  }
630 
638  private function getThumbPrevText( $params, $sizeLinkBigImagePreview ) {
639  if ( $sizeLinkBigImagePreview ) {
640  // Show a different message of preview is different format from original.
641  $previewTypeDiffers = false;
642  $origExt = $thumbExt = $this->displayImg->getExtension();
643  if ( $this->displayImg->getHandler() ) {
644  $origMime = $this->displayImg->getMimeType();
645  $typeParams = $params;
646  $this->displayImg->getHandler()->normaliseParams( $this->displayImg, $typeParams );
647  list( $thumbExt, $thumbMime ) = $this->displayImg->getHandler()->getThumbType(
648  $origExt, $origMime, $typeParams );
649  if ( $thumbMime !== $origMime ) {
650  $previewTypeDiffers = true;
651  }
652  }
653  if ( $previewTypeDiffers ) {
654  return $this->getContext()->msg( 'show-big-image-preview-differ' )->
655  rawParams( $sizeLinkBigImagePreview )->
656  params( strtoupper( $origExt ) )->
657  params( strtoupper( $thumbExt ) )->
658  parse();
659  } else {
660  return $this->getContext()->msg( 'show-big-image-preview' )->
661  rawParams( $sizeLinkBigImagePreview )->
662  parse();
663  }
664  } else {
665  return '';
666  }
667  }
668 
676  private function makeSizeLink( $params, $width, $height ) {
677  $params['width'] = $width;
678  $params['height'] = $height;
679  $thumbnail = $this->displayImg->transform( $params );
680  if ( $thumbnail && !$thumbnail->isError() ) {
681  return Html::rawElement( 'a', [
682  'href' => $thumbnail->getUrl(),
683  'class' => 'mw-thumbnail-link'
684  ], $this->getContext()->msg( 'show-big-image-size' )->numParams(
685  $thumbnail->getWidth(), $thumbnail->getHeight()
686  )->parse() );
687  } else {
688  return '';
689  }
690  }
691 
695  protected function printSharedImageText() {
696  $out = $this->getContext()->getOutput();
697  $this->loadFile();
698 
699  $descUrl = $this->mPage->getFile()->getDescriptionUrl();
700  $descText = $this->mPage->getFile()->getDescriptionText( $this->getContext()->getLanguage() );
701 
702  /* Add canonical to head if there is no local page for this shared file */
703  if ( $descUrl && $this->mPage->getId() == 0 ) {
704  $out->setCanonicalUrl( $descUrl );
705  }
706 
707  $wrap = "<div class=\"sharedUploadNotice\">\n$1\n</div>\n";
708  $repo = $this->mPage->getFile()->getRepo()->getDisplayName();
709 
710  if ( $descUrl &&
711  $descText &&
712  $this->getContext()->msg( 'sharedupload-desc-here' )->plain() !== '-'
713  ) {
714  $out->wrapWikiMsg( $wrap, [ 'sharedupload-desc-here', $repo, $descUrl ] );
715  } elseif ( $descUrl &&
716  $this->getContext()->msg( 'sharedupload-desc-there' )->plain() !== '-'
717  ) {
718  $out->wrapWikiMsg( $wrap, [ 'sharedupload-desc-there', $repo, $descUrl ] );
719  } else {
720  $out->wrapWikiMsg( $wrap, [ 'sharedupload', $repo ], ''/*BACKCOMPAT*/ );
721  }
722 
723  if ( $descText ) {
724  $this->mExtraDescription = $descText;
725  }
726  }
727 
728  public function getUploadUrl() {
729  $this->loadFile();
730  $uploadTitle = SpecialPage::getTitleFor( 'Upload' );
731  return $uploadTitle->getFullURL( [
732  'wpDestFile' => $this->mPage->getFile()->getName(),
733  'wpForReUpload' => 1
734  ] );
735  }
736 
741  protected function uploadLinksBox() {
743 
744  if ( !$wgEnableUploads ) {
745  return;
746  }
747 
748  $this->loadFile();
749  if ( !$this->mPage->getFile()->isLocal() ) {
750  return;
751  }
752 
753  $out = $this->getContext()->getOutput();
754  $out->addHTML( "<ul>\n" );
755 
756  # "Upload a new version of this file" link
757  $canUpload = $this->getTitle()->quickUserCan( 'upload', $this->getContext()->getUser() );
758  if ( $canUpload && UploadBase::userCanReUpload(
759  $this->getContext()->getUser(),
760  $this->mPage->getFile() )
761  ) {
762  $ulink = Linker::makeExternalLink(
763  $this->getUploadUrl(),
764  $this->getContext()->msg( 'uploadnewversion-linktext' )->text()
765  );
766  $out->addHTML( "<li id=\"mw-imagepage-reupload-link\">"
767  . "<div class=\"plainlinks\">{$ulink}</div></li>\n" );
768  } else {
769  $out->addHTML( "<li id=\"mw-imagepage-upload-disallowed\">"
770  . $this->getContext()->msg( 'upload-disallowed-here' )->escaped() . "</li>\n" );
771  }
772 
773  $out->addHTML( "</ul>\n" );
774  }
775 
779  protected function closeShowImage() {
780  }
781 
786  protected function imageHistory() {
787  $this->loadFile();
788  $out = $this->getContext()->getOutput();
789  $pager = new ImageHistoryPseudoPager( $this );
790  $out->addHTML( $pager->getBody() );
791  $out->preventClickjacking( $pager->getPreventClickjacking() );
792 
793  $this->mPage->getFile()->resetHistory(); // free db resources
794 
795  # Exist check because we don't want to show this on pages where an image
796  # doesn't exist along with the noimage message, that would suck. -ævar
797  if ( $this->mPage->getFile()->exists() ) {
798  $this->uploadLinksBox();
799  }
800  }
801 
807  protected function queryImageLinks( $target, $limit ) {
808  $dbr = wfGetDB( DB_REPLICA );
809 
810  return $dbr->select(
811  [ 'imagelinks', 'page' ],
812  [ 'page_namespace', 'page_title', 'il_to' ],
813  [ 'il_to' => $target, 'il_from = page_id' ],
814  __METHOD__,
815  [ 'LIMIT' => $limit + 1, 'ORDER BY' => 'il_from', ]
816  );
817  }
818 
819  protected function imageLinks() {
820  $limit = 100;
821 
822  $out = $this->getContext()->getOutput();
823 
824  $rows = [];
825  $redirects = [];
826  foreach ( $this->getTitle()->getRedirectsHere( NS_FILE ) as $redir ) {
827  $redirects[$redir->getDBkey()] = [];
828  $rows[] = (object)[
829  'page_namespace' => NS_FILE,
830  'page_title' => $redir->getDBkey(),
831  ];
832  }
833 
834  $res = $this->queryImageLinks( $this->getTitle()->getDBkey(), $limit + 1 );
835  foreach ( $res as $row ) {
836  $rows[] = $row;
837  }
838  $count = count( $rows );
839 
840  $hasMore = $count > $limit;
841  if ( !$hasMore && count( $redirects ) ) {
842  $res = $this->queryImageLinks( array_keys( $redirects ),
843  $limit - count( $rows ) + 1 );
844  foreach ( $res as $row ) {
845  $redirects[$row->il_to][] = $row;
846  $count++;
847  }
848  $hasMore = ( $res->numRows() + count( $rows ) ) > $limit;
849  }
850 
851  if ( $count == 0 ) {
852  $out->wrapWikiMsg(
853  Html::rawElement( 'div',
854  [ 'id' => 'mw-imagepage-nolinkstoimage' ], "\n$1\n" ),
855  'nolinkstoimage'
856  );
857  return;
858  }
859 
860  $out->addHTML( "<div id='mw-imagepage-section-linkstoimage'>\n" );
861  if ( !$hasMore ) {
862  $out->addWikiMsg( 'linkstoimage', $count );
863  } else {
864  // More links than the limit. Add a link to [[Special:Whatlinkshere]]
865  $out->addWikiMsg( 'linkstoimage-more',
866  $this->getContext()->getLanguage()->formatNum( $limit ),
867  $this->getTitle()->getPrefixedDBkey()
868  );
869  }
870 
871  $out->addHTML(
872  Html::openElement( 'ul',
873  [ 'class' => 'mw-imagepage-linkstoimage' ] ) . "\n"
874  );
875  $count = 0;
876 
877  // Sort the list by namespace:title
878  usort( $rows, [ $this, 'compare' ] );
879 
880  // Create links for every element
881  $currentCount = 0;
882  foreach ( $rows as $element ) {
883  $currentCount++;
884  if ( $currentCount > $limit ) {
885  break;
886  }
887 
888  $query = [];
889  # Add a redirect=no to make redirect pages reachable
890  if ( isset( $redirects[$element->page_title] ) ) {
891  $query['redirect'] = 'no';
892  }
894  Title::makeTitle( $element->page_namespace, $element->page_title ),
895  null, [], $query
896  );
897  if ( !isset( $redirects[$element->page_title] ) ) {
898  # No redirects
899  $liContents = $link;
900  } elseif ( count( $redirects[$element->page_title] ) === 0 ) {
901  # Redirect without usages
902  $liContents = $this->getContext()->msg( 'linkstoimage-redirect' )
903  ->rawParams( $link, '' )
904  ->parse();
905  } else {
906  # Redirect with usages
907  $li = '';
908  foreach ( $redirects[$element->page_title] as $row ) {
909  $currentCount++;
910  if ( $currentCount > $limit ) {
911  break;
912  }
913 
914  $link2 = Linker::linkKnown( Title::makeTitle( $row->page_namespace, $row->page_title ) );
915  $li .= Html::rawElement(
916  'li',
917  [ 'class' => 'mw-imagepage-linkstoimage-ns' . $element->page_namespace ],
918  $link2
919  ) . "\n";
920  }
921 
923  'ul',
924  [ 'class' => 'mw-imagepage-redirectstofile' ],
925  $li
926  ) . "\n";
927  $liContents = $this->getContext()->msg( 'linkstoimage-redirect' )->rawParams(
928  $link, $ul )->parse();
929  }
930  $out->addHTML( Html::rawElement(
931  'li',
932  [ 'class' => 'mw-imagepage-linkstoimage-ns' . $element->page_namespace ],
933  $liContents
934  ) . "\n"
935  );
936 
937  };
938  $out->addHTML( Html::closeElement( 'ul' ) . "\n" );
939  $res->free();
940 
941  // Add a links to [[Special:Whatlinkshere]]
942  if ( $count > $limit ) {
943  $out->addWikiMsg( 'morelinkstoimage', $this->getTitle()->getPrefixedDBkey() );
944  }
945  $out->addHTML( Html::closeElement( 'div' ) . "\n" );
946  }
947 
948  protected function imageDupes() {
949  $this->loadFile();
950  $out = $this->getContext()->getOutput();
951 
952  $dupes = $this->mPage->getDuplicates();
953  if ( count( $dupes ) == 0 ) {
954  return;
955  }
956 
957  $out->addHTML( "<div id='mw-imagepage-section-duplicates'>\n" );
958  $out->addWikiMsg( 'duplicatesoffile',
959  $this->getContext()->getLanguage()->formatNum( count( $dupes ) ), $this->getTitle()->getDBkey()
960  );
961  $out->addHTML( "<ul class='mw-imagepage-duplicates'>\n" );
962 
966  foreach ( $dupes as $file ) {
967  $fromSrc = '';
968  if ( $file->isLocal() ) {
969  $link = Linker::linkKnown( $file->getTitle() );
970  } else {
971  $link = Linker::makeExternalLink( $file->getDescriptionUrl(),
972  $file->getTitle()->getPrefixedText() );
973  $fromSrc = $this->getContext()->msg(
974  'shared-repo-from',
975  $file->getRepo()->getDisplayName()
976  )->text();
977  }
978  $out->addHTML( "<li>{$link} {$fromSrc}</li>\n" );
979  }
980  $out->addHTML( "</ul></div>\n" );
981  }
982 
986  public function delete() {
987  $file = $this->mPage->getFile();
988  if ( !$file->exists() || !$file->isLocal() || $file->getRedirected() ) {
989  // Standard article deletion
990  parent::delete();
991  return;
992  }
993 
994  $deleter = new FileDeleteForm( $file );
995  $deleter->execute();
996  }
997 
1003  function showError( $description ) {
1004  $out = $this->getContext()->getOutput();
1005  $out->setPageTitle( $this->getContext()->msg( 'internalerror' ) );
1006  $out->setRobotPolicy( 'noindex,nofollow' );
1007  $out->setArticleRelated( false );
1008  $out->enableClientCache( false );
1009  $out->addWikiText( $description );
1010  }
1011 
1020  protected function compare( $a, $b ) {
1021  if ( $a->page_namespace == $b->page_namespace ) {
1022  return strcmp( $a->page_title, $b->page_title );
1023  } else {
1024  return $a->page_namespace - $b->page_namespace;
1025  }
1026  }
1027 
1036  public function getImageLimitsFromOption( $user, $optionName ) {
1038 
1039  $option = $user->getIntOption( $optionName );
1040  if ( !isset( $wgImageLimits[$option] ) ) {
1041  $option = User::getDefaultOption( $optionName );
1042  }
1043 
1044  // The user offset might still be incorrect, specially if
1045  // $wgImageLimits got changed (see bug #8858).
1046  if ( !isset( $wgImageLimits[$option] ) ) {
1047  // Default to the first offset in $wgImageLimits
1048  $option = 0;
1049  }
1050 
1051  return isset( $wgImageLimits[$option] )
1052  ? $wgImageLimits[$option]
1053  : [ 800, 600 ]; // if nothing is set, fallback to a hardcoded default
1054  }
1055 
1064  protected function doRenderLangOpt( array $langChoices, $curLang, $defaultLang ) {
1065  global $wgScript;
1066  sort( $langChoices );
1067  $curLang = wfBCP47( $curLang );
1068  $defaultLang = wfBCP47( $defaultLang );
1069  $opts = '';
1070  $haveCurrentLang = false;
1071  $haveDefaultLang = false;
1072 
1073  // We make a list of all the language choices in the file.
1074  // Additionally if the default language to render this file
1075  // is not included as being in this file (for example, in svgs
1076  // usually the fallback content is the english content) also
1077  // include a choice for that. Last of all, if we're viewing
1078  // the file in a language not on the list, add it as a choice.
1079  foreach ( $langChoices as $lang ) {
1080  $code = wfBCP47( $lang );
1081  $name = Language::fetchLanguageName( $code, $this->getContext()->getLanguage()->getCode() );
1082  if ( $name !== '' ) {
1083  $display = $this->getContext()->msg( 'img-lang-opt', $code, $name )->text();
1084  } else {
1085  $display = $code;
1086  }
1087  $opts .= "\n" . Xml::option( $display, $code, $curLang === $code );
1088  if ( $curLang === $code ) {
1089  $haveCurrentLang = true;
1090  }
1091  if ( $defaultLang === $code ) {
1092  $haveDefaultLang = true;
1093  }
1094  }
1095  if ( !$haveDefaultLang ) {
1096  // Its hard to know if the content is really in the default language, or
1097  // if its just unmarked content that could be in any language.
1098  $opts = Xml::option(
1099  $this->getContext()->msg( 'img-lang-default' )->text(),
1100  $defaultLang,
1101  $defaultLang === $curLang
1102  ) . $opts;
1103  }
1104  if ( !$haveCurrentLang && $defaultLang !== $curLang ) {
1105  $name = Language::fetchLanguageName( $curLang, $this->getContext()->getLanguage()->getCode() );
1106  if ( $name !== '' ) {
1107  $display = $this->getContext()->msg( 'img-lang-opt', $curLang, $name )->text();
1108  } else {
1109  $display = $curLang;
1110  }
1111  $opts = Xml::option( $display, $curLang, true ) . $opts;
1112  }
1113 
1114  $select = Html::rawElement(
1115  'select',
1116  [ 'id' => 'mw-imglangselector', 'name' => 'lang' ],
1117  $opts
1118  );
1119  $submit = Xml::submitButton( $this->getContext()->msg( 'img-lang-go' )->text() );
1120 
1121  $formContents = $this->getContext()->msg( 'img-lang-info' )
1122  ->rawParams( $select, $submit )
1123  ->parse();
1124  $formContents .= Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() );
1125 
1126  $langSelectLine = Html::rawElement( 'div', [ 'id' => 'mw-imglangselector-line' ],
1127  Html::rawElement( 'form', [ 'action' => $wgScript ], $formContents )
1128  );
1129  return $langSelectLine;
1130  }
1131 
1146  protected function getDisplayWidthHeight( $maxWidth, $maxHeight, $width, $height ) {
1147  if ( !$maxWidth || !$maxHeight ) {
1148  // should never happen
1149  throw new MWException( 'Using a choice from $wgImageLimits that is 0x0' );
1150  }
1151 
1152  if ( !$width || !$height ) {
1153  return [ 0, 0 ];
1154  }
1155 
1156  # Calculate the thumbnail size.
1157  if ( $width <= $maxWidth && $height <= $maxHeight ) {
1158  // Vectorized image, do nothing.
1159  } elseif ( $width / $height >= $maxWidth / $maxHeight ) {
1160  # The limiting factor is the width, not the height.
1161  $height = round( $height * $maxWidth / $width );
1162  $width = $maxWidth;
1163  # Note that $height <= $maxHeight now.
1164  } else {
1165  $newwidth = floor( $width * $maxHeight / $height );
1166  $height = round( $height * $newwidth / $width );
1167  $width = $newwidth;
1168  # Note that $height <= $maxHeight now, but might not be identical
1169  # because of rounding.
1170  }
1171  return [ $width, $height ];
1172  }
1173 
1182  protected function getThumbSizes( $origWidth, $origHeight ) {
1184  if ( $this->displayImg->getRepo()->canTransformVia404() ) {
1185  $thumbSizes = $wgImageLimits;
1186  // Also include the full sized resolution in the list, so
1187  // that users know they can get it. This will link to the
1188  // original file asset if mustRender() === false. In the case
1189  // that we mustRender, some users have indicated that they would
1190  // find it useful to have the full size image in the rendered
1191  // image format.
1192  $thumbSizes[] = [ $origWidth, $origHeight ];
1193  } else {
1194  # Creating thumb links triggers thumbnail generation.
1195  # Just generate the thumb for the current users prefs.
1196  $thumbSizes = [
1197  $this->getImageLimitsFromOption( $this->getContext()->getUser(), 'thumbsize' )
1198  ];
1199  if ( !$this->displayImg->mustRender() ) {
1200  // We can safely include a link to the "full-size" preview,
1201  // without actually rendering.
1202  $thumbSizes[] = [ $origWidth, $origHeight ];
1203  }
1204  }
1205  return $thumbSizes;
1206  }
1207 
1212  public function getFile() {
1213  return $this->mPage->getFile();
1214  }
1215 
1220  public function isLocal() {
1221  return $this->mPage->isLocal();
1222  }
1223 
1228  public function getDuplicates() {
1229  return $this->mPage->getDuplicates();
1230  }
1231 
1236  public function getForeignCategories() {
1237  $this->mPage->getForeignCategories();
1238  }
1239 
1240 }
User\getDefaultOption
static getDefaultOption( $opt)
Get a given default option value.
Definition: User.php:1603
ImagePage\makeSizeLink
makeSizeLink( $params, $width, $height)
Creates an thumbnail of specified size and returns an HTML link to it.
Definition: ImagePage.php:676
ImagePage\$mPage
WikiFilePage $mPage
Definition: ImagePage.php:46
ImagePage\getForeignCategories
getForeignCategories()
Definition: ImagePage.php:1236
object
globals will be eliminated from MediaWiki replaced by an application object which would be passed to constructors Whether that would be an convenient solution remains to be but certainly PHP makes such object oriented programming models easier than they were in previous versions For the time being MediaWiki programmers will have to work in an environment with some global context At the time of globals were initialised on startup by MediaWiki of these were configuration which are documented in DefaultSettings php There is no comprehensive documentation for the remaining however some of the most important ones are listed below They are typically initialised either in index php or in Setup php For a description of the see design txt $wgTitle Title object created from the request URL $wgOut OutputPage object for HTTP response $wgUser User object for the user associated with the current request $wgLang Language object selected by user preferences $wgContLang Language object associated with the wiki being viewed $wgParser Parser object Parser extensions register their hooks here $wgRequest WebRequest object
Definition: globals.txt:25
wfBCP47
wfBCP47( $code)
Get the normalised IETF language tag See unit test for examples.
Definition: GlobalFunctions.php:3370
$request
error also a ContextSource you ll probably need to make sure the header is varied on $request
Definition: hooks.txt:2612
ImagePage\getUploadUrl
getUploadUrl()
Definition: ImagePage.php:728
Xml\tags
static tags( $element, $attribs=null, $contents)
Same as Xml::element(), but does not escape contents.
Definition: Xml.php:131
ImagePage\closeShowImage
closeShowImage()
For overloading.
Definition: ImagePage.php:779
ImagePage\openShowImage
openShowImage()
Definition: ImagePage.php:299
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:33
view
$article view()
captcha-old.count
count
Definition: captcha-old.py:225
text
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add text
Definition: design.txt:12
ImagePage\getFile
getFile()
Definition: ImagePage.php:1212
$wgScript
$wgScript
The URL path to index.php.
Definition: DefaultSettings.php:202
$wgSVGMaxSize
$wgSVGMaxSize
Don't scale a SVG larger than this.
Definition: DefaultSettings.php:1115
ImagePage\$fileLoaded
bool $fileLoaded
Definition: ImagePage.php:38
ImagePage\uploadLinksBox
uploadLinksBox()
Print out the various links at the bottom of the image page, e.g.
Definition: ImagePage.php:741
ImagePage\doRenderLangOpt
doRenderLangOpt(array $langChoices, $curLang, $defaultLang)
Output a drop-down box for language options for the file.
Definition: ImagePage.php:1064
use
as see the revision history and available at free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
Definition: MIT-LICENSE.txt:10
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:246
NS_FILE
const NS_FILE
Definition: Defines.php:68
$params
$params
Definition: styleTest.css.php:40
Xml\option
static option( $text, $value=null, $selected=false, $attribs=[])
Convenience function to build an HTML drop-down list item.
Definition: Xml.php:484
Linker\linkKnown
static linkKnown( $target, $html=null, $customAttribs=[], $query=[], $options=[ 'known'])
Identical to link(), except $options defaults to 'known'.
Definition: Linker.php:159
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:82
Linker\processResponsiveImages
static processResponsiveImages( $file, $thumb, $hp)
Process responsive images: add 1.5x and 2x subimages to the thumbnail, where applicable.
Definition: Linker.php:650
$res
$res
Definition: database.txt:21
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:304
ImagePage
Class for viewing MediaWiki file description pages.
Definition: ImagePage.php:30
Wikimedia\Rdbms\ResultWrapper
Result wrapper for grabbing data queried from an IDatabase object.
Definition: ResultWrapper.php:24
$type
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached my talk my contributions etc etc otherwise the built in rate limiting checks are if enabled allows for interception of redirect as a string mapping parameter names to values & $type
Definition: hooks.txt:2536
ImagePage\render
render()
Handler for action=render Include body text only; none of the image extras.
Definition: ImagePage.php:93
wfMessageFallback
wfMessageFallback()
This function accepts multiple message keys and returns a message instance for the first message whic...
Definition: GlobalFunctions.php:1395
ImagePage\setFile
setFile( $file)
Definition: ImagePage.php:61
Xml\openElement
static openElement( $element, $attribs=null)
This opens an XML element.
Definition: Xml.php:109
php
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
ImagePage\$repo
FileRepo $repo
Definition: ImagePage.php:35
FileRepo
Base class for file repositories.
Definition: FileRepo.php:37
Html\closeElement
static closeElement( $element)
Returns "</$element>".
Definition: Html.php:309
$query
null for the wiki Added should default to null in handler for backwards compatibility add a value to it if you want to add a cookie that have to vary cache options can modify $query
Definition: hooks.txt:1572
File
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition: File.php:51
$html
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses & $html
Definition: hooks.txt:1956
MWException
MediaWiki exception.
Definition: MWException.php:26
$title
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:934
Article\getTitle
getTitle()
Get the title object of the article.
Definition: Article.php:174
$css
$css
Definition: styleTest.css.php:50
ImagePage\showTOC
showTOC( $metadata)
Create the TOC.
Definition: ImagePage.php:237
ImagePage\imageLinks
imageLinks()
Definition: ImagePage.php:819
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:3060
$page
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached $page
Definition: hooks.txt:2536
ImagePage\getDisplayWidthHeight
getDisplayWidthHeight( $maxWidth, $maxHeight, $width, $height)
Get the width and height to display image at.
Definition: ImagePage.php:1146
$limit
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist Do not use this to implement individual filters if they are compatible with the ChangesListFilter and ChangesListFilterGroup structure use sub classes of those in conjunction with the ChangesListSpecialPageStructuredFilters hook This hook can be used to implement filters that do not implement that or custom behavior that is not an individual filter e g Watchlist and Watchlist you will want to construct new ChangesListBooleanFilter or ChangesListStringOptionsFilter objects When constructing you specify which group they belong to You can reuse existing or create your you must register them with $special registerFilterGroup removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context the output can only depend on parameters provided to this hook not on global state indicating whether full HTML should be generated If generation of HTML may be but other information should still be present in the ParserOutput object to manipulate or replace but no entry for that model exists in $wgContentHandlers please use GetContentModels hook to make them known to core if desired whether it is OK to use $contentModel on $title Handler functions that modify $ok should generally return false to prevent further hooks from further modifying $ok inclusive $limit
Definition: hooks.txt:1049
Xml\element
static element( $element, $attribs=null, $contents='', $allowShortTag=true)
Format an XML element with given attributes and, optionally, text content.
Definition: Xml.php:39
ImagePage\newPage
newPage(Title $title)
Definition: ImagePage.php:52
Article\getContext
getContext()
Gets the context this Article is executed in.
Definition: Article.php:1932
FileDeleteForm
File deletion user interface.
Definition: FileDeleteForm.php:31
div
div
Definition: parserTests.txt:6533
$output
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist Do not use this to implement individual filters if they are compatible with the ChangesListFilter and ChangesListFilterGroup structure use sub classes of those in conjunction with the ChangesListSpecialPageStructuredFilters hook This hook can be used to implement filters that do not implement that or custom behavior that is not an individual filter e g Watchlist and Watchlist you will want to construct new ChangesListBooleanFilter or ChangesListStringOptionsFilter objects When constructing you specify which group they belong to You can reuse existing or create your you must register them with $special registerFilterGroup removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context the output can only depend on parameters provided to this hook not on global state indicating whether full HTML should be generated If generation of HTML may be but other information should still be present in the ParserOutput object & $output
Definition: hooks.txt:1049
Linker\makeExternalLink
static makeExternalLink( $url, $text, $escape=true, $linktype='', $attribs=[], $title=null)
Make an external link.
Definition: Linker.php:838
Title\makeTitle
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:514
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
LogEventsList\showLogExtract
static showLogExtract(&$out, $types=[], $page='', $user='', $param=[])
Show log extract.
Definition: LogEventsList.php:564
DB_REPLICA
const DB_REPLICA
Definition: defines.php:25
list
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition: deferred.txt:11
ImagePage\showError
showError( $description)
Display an error with a wikitext description.
Definition: ImagePage.php:1003
ImagePage\view
view()
This is the default action of the index.php entry point: just view the page of the given title.
Definition: ImagePage.php:98
ImagePage\imageDupes
imageDupes()
Definition: ImagePage.php:948
Html\hidden
static hidden( $name, $value, array $attribs=[])
Convenience function to produce an input element with type=hidden.
Definition: Html.php:746
FileRepo\getDisplayName
getDisplayName()
Get the human-readable name of the repo.
Definition: FileRepo.php:1765
ImagePage\makeMetadataTable
makeMetadataTable( $metadata)
Make a table with metadata to be shown in the output page.
Definition: ImagePage.php:263
ImagePage\getThumbPrevText
getThumbPrevText( $params, $sizeLinkBigImagePreview)
Make the text under the image to say what size preview.
Definition: ImagePage.php:638
ImagePage\getThumbSizes
getThumbSizes( $origWidth, $origHeight)
Get alternative thumbnail sizes.
Definition: ImagePage.php:1182
$ul
$ul
Definition: upgradeLogging.php:180
ImagePage\$displayImg
File $displayImg
Definition: ImagePage.php:32
wfEscapeWikiText
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
Definition: GlobalFunctions.php:1657
ImagePage\getDisplayedFile
getDisplayedFile()
Definition: ImagePage.php:226
Article\getUser
getUser( $audience=Revision::FOR_PUBLIC, User $user=null)
Call to WikiPage function for backwards compatibility.
Definition: Article.php:2259
Language\fetchLanguageName
static fetchLanguageName( $code, $inLanguage=null, $include='all')
Definition: Language.php:891
$handler
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output modifiable modifiable after all normalizations have been except for the $wgMaxImageArea check set to true or false to override the $wgMaxImageArea check result gives extension the possibility to transform it themselves $handler
Definition: hooks.txt:783
plain
either a plain
Definition: hooks.txt:2007
wfFindFile
wfFindFile( $title, $options=[])
Find a file.
Definition: GlobalFunctions.php:3101
$wgImageLimits
$wgImageLimits
Limit images on image description pages to a user-selectable limit.
Definition: DefaultSettings.php:1343
Title
Represents a title within MediaWiki.
Definition: Title.php:39
ImagePage\queryImageLinks
queryImageLinks( $target, $limit)
Definition: ImagePage.php:807
Xml\closeElement
static closeElement( $element)
Shortcut to close an XML element.
Definition: Xml.php:118
$dbr
if(! $regexes) $dbr
Definition: cleanup.php:94
$ext
$ext
Definition: NoLocalSettings.php:25
$code
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output modifiable & $code
Definition: hooks.txt:783
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
Html\openElement
static openElement( $element, $attribs=[])
Identical to rawElement(), but has no third parameter and omits the end tag (and the self-closing '/'...
Definition: Html.php:251
Html\rawElement
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:209
$wgEnableUploads
$wgEnableUploads
Uploads have to be specially set up to be secure.
Definition: DefaultSettings.php:378
$link
usually copyright or history_copyright This message must be in HTML not wikitext & $link
Definition: hooks.txt:2929
ImagePage\getContentObject
getContentObject()
Overloading Article's getContentObject method.
Definition: ImagePage.php:291
ImagePage\compare
compare( $a, $b)
Callback for usort() to do link sorts by (namespace, title) Function copied from Title::compare()
Definition: ImagePage.php:1020
Article\getId
getId()
Call to WikiPage function for backwards compatibility.
Definition: Article.php:2171
ImagePage\getImageLimitsFromOption
getImageLimitsFromOption( $user, $optionName)
Returns the corresponding $wgImageLimits entry for the selected user option.
Definition: ImagePage.php:1036
WikiFilePage
Special handling for file pages.
Definition: WikiFilePage.php:30
ImageHistoryPseudoPager
Definition: ImageHistoryPseudoPager.php:21
Article
Class for viewing MediaWiki article and history.
Definition: Article.php:35
ImagePage\loadFile
loadFile()
Definition: ImagePage.php:67
ImagePage\isLocal
isLocal()
Definition: ImagePage.php:1220
Article\getOldID
getOldID()
Definition: Article.php:243
wfLocalFile
wfLocalFile( $title)
Get an object referring to a locally registered file.
Definition: GlobalFunctions.php:3112
Linker\makeThumbLinkObj
static makeThumbLinkObj(Title $title, $file, $label='', $alt, $align='right', $params=[], $framed=false, $manualthumb="")
Make HTML for a thumbnail including image, border and caption.
Definition: Linker.php:502
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:131
ImagePage\$mExtraDescription
bool $mExtraDescription
Definition: ImagePage.php:41
$wgShowEXIF
$wgShowEXIF
Show Exif data, on by default if available.
Definition: DefaultSettings.php:669
$options
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist Do not use this to implement individual filters if they are compatible with the ChangesListFilter and ChangesListFilterGroup structure use sub classes of those in conjunction with the ChangesListSpecialPageStructuredFilters hook This hook can be used to implement filters that do not implement that or custom behavior that is not an individual filter e g Watchlist and Watchlist you will want to construct new ChangesListBooleanFilter or ChangesListStringOptionsFilter objects When constructing you specify which group they belong to You can reuse existing or create your you must register them with $special registerFilterGroup removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context $options
Definition: hooks.txt:1049
Article\viewRedirect
viewRedirect( $target, $appendSubtitle=true, $forceKnown=false)
Return the HTML for the top of a redirect page.
Definition: Article.php:1428
ImagePage\getDuplicates
getDuplicates()
Definition: ImagePage.php:1228
ImagePage\printSharedImageText
printSharedImageText()
Show a notice that the file is from a shared repository.
Definition: ImagePage.php:695
array
the array() calling protocol came about after MediaWiki 1.4rc1.
ImagePage\imageHistory
imageHistory()
If the page we've just displayed is in the "Image" namespace, we follow it with an upload history of ...
Definition: ImagePage.php:786
Xml\submitButton
static submitButton( $value, $attribs=[])
Convenience function to build an HTML submit button When $wgUseMediaWikiUIEverywhere is true it will ...
Definition: Xml.php:459
$out
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output $out
Definition: hooks.txt:783