36 private $filename =
'';
51 parent::__construct(
'FileDuplicateSearch' );
60 private function getDupes() {
61 return $this->repoGroup->findBySha1( $this->hash );
67 private function showList( $dupes ) {
69 $html[] =
"<ol class='special'>";
71 foreach ( $dupes as $dupe ) {
72 $line = $this->formatResult( $dupe );
73 $html[] =
"<li>" . $line .
"</li>";
77 $this->
getOutput()->addHTML( implode(
"\n", $html ) );
85 $this->filename = $par ?? $this->
getRequest()->getText(
'filename' );
88 $title = Title::newFromText( $this->filename,
NS_FILE );
89 if ( $title && $title->getText() !=
'' ) {
90 $this->file = $this->repoGroup->findFile( $title );
95 # Create the input form
100 'label-message' =>
'fileduplicatesearch-filename',
103 'default' => $this->filename,
106 $htmlForm = HTMLForm::factory(
'ooui', $formFields, $this->
getContext() );
108 $htmlForm->setMethod(
'get' );
109 $htmlForm->setSubmitTextMsg( $this->
msg(
'fileduplicatesearch-submit' ) );
113 $htmlForm->prepareForm()->displayForm(
false );
116 $this->hash = $this->file->getSha1();
117 } elseif ( $this->filename !==
'' ) {
119 "<p class='mw-fileduplicatesearch-noresults'>\n$1\n</p>",
124 if ( $this->hash !=
'' ) {
125 # Show a thumbnail of the file
128 $thumb = $img->transform( [
'width' => 120,
'height' => 120 ] );
130 $out->addModuleStyles(
'mediawiki.special' );
131 $out->addHTML(
'<div id="mw-fileduplicatesearch-icon">' .
132 $thumb->toHtml( [
'desc-link' =>
false ] ) .
'<br />' .
133 $this->msg(
'fileduplicatesearch-info' )
134 ->numParams( $img->getWidth(), $img->getHeight() )
135 ->sizeParams( $img->getSize() )
136 ->params( $img->getMimeType() )->parseAsBlock() .
141 $dupes = $this->getDupes();
142 $numRows = count( $dupes );
144 # Show a short summary
145 if ( $numRows == 1 ) {
147 "<p class='mw-fileduplicatesearch-result-1'>\n$1\n</p>",
150 } elseif ( $numRows ) {
152 "<p class='mw-fileduplicatesearch-result-n'>\n$1\n</p>",
158 $this->doBatchLookups( $dupes );
159 $this->showList( $dupes );
166 private function doBatchLookups( $list ) {
167 $batch = $this->linkBatchFactory->newLinkBatch()->setCaller( __METHOD__ );
168 foreach ( $list as $file ) {
169 $batch->addObj( $file->getTitle() );
170 if ( $file->isLocal() ) {
171 $uploader = $file->getUploader( File::FOR_THIS_USER, $this->
getAuthority() );
173 $batch->addUser( $uploader );
185 private function formatResult( $result ) {
187 $nt = $result->getTitle();
188 $text = $this->languageConverter->convert( $nt->getText() );
189 $plink = $linkRenderer->makeLink(
194 $uploader = $result->getUploader( File::FOR_THIS_USER, $this->
getAuthority() );
195 if ( $result->isLocal() && $uploader ) {
196 $user = Linker::userLink( $uploader->getId(), $uploader->getName() );
197 $user .=
'<span style="white-space: nowrap;">';
198 $user .= Linker::userToolLinks( $uploader->getId(), $uploader->getName() );
200 } elseif ( $uploader ) {
201 $user = htmlspecialchars( $uploader->getName() );
203 $user =
'<span class="history-deleted">'
204 . $this->
msg(
'rev-deleted-user' )->escaped() .
'</span>';
207 $time = htmlspecialchars( $this->
getLanguage()->userTimeAndDate(
208 $result->getTimestamp(), $this->getUser() ) );
210 return "$plink . . $user . . $time";
222 $title = Title::newFromText( $search,
NS_FILE );
223 if ( !$title || $title->getNamespace() !==
NS_FILE ) {
227 $searchEngine = $this->searchEngineFactory->create();
228 $searchEngine->setLimitOffset( $limit, $offset );
230 $searchEngine->setNamespaces( [
NS_FILE ] );
231 $result = $searchEngine->defaultPrefixSearch( $search );
233 return array_map(
static function (
Title $t ) {
235 return $t->getText();
246class_alias( SpecialFileDuplicateSearch::class,
'SpecialFileDuplicateSearch' );
wfEscapeWikiText( $input)
Escapes the given text so that it may be output using addWikiText() without any linking,...
Factory for LinkBatch objects to batch query page metadata.
Parent class for all special pages.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getPageTitle( $subpage=false)
Get a self-referential title object.
getContext()
Gets the context this SpecialPage is executed in.
getRequest()
Get the WebRequest being used for this instance.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getOutput()
Get the OutputPage being used for this instance.
getAuthority()
Shortcut to get the Authority executing this instance.
getContentLanguage()
Shortcut to get content language.
getLanguage()
Shortcut to get user's language.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages By default the message key is the canonical name of...