2020-04-20 13:34:12 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace PageImages\Hooks;
|
|
|
|
|
2021-05-14 23:16:41 +00:00
|
|
|
use MediaWiki\Page\PageIdentity;
|
2020-04-20 13:34:12 +00:00
|
|
|
use MediaWiki\Search\Entity\SearchResultThumbnail;
|
2022-08-23 12:24:38 +00:00
|
|
|
use MediaWiki\Search\Hook\SearchResultProvideThumbnailHook;
|
2020-04-20 13:34:12 +00:00
|
|
|
use PageImages\PageImages;
|
|
|
|
use PageProps;
|
|
|
|
use RepoGroup;
|
|
|
|
use Title;
|
|
|
|
|
2022-06-15 16:08:43 +00:00
|
|
|
class SearchResultProvideThumbnailHookHandler implements SearchResultProvideThumbnailHook {
|
2020-04-20 13:34:12 +00:00
|
|
|
|
2020-05-19 23:27:08 +00:00
|
|
|
public const THUMBNAIL_SIZE = 200;
|
2020-04-20 13:34:12 +00:00
|
|
|
|
|
|
|
/** @var PageProps */
|
|
|
|
private $pageProps;
|
|
|
|
|
|
|
|
/** @var RepoGroup */
|
|
|
|
private $repoGroup;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param PageProps $pageProps
|
|
|
|
* @param RepoGroup $repoGroup
|
|
|
|
*/
|
|
|
|
public function __construct( PageProps $pageProps, RepoGroup $repoGroup ) {
|
|
|
|
$this->pageProps = $pageProps;
|
|
|
|
$this->repoGroup = $repoGroup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a list fileNames associated with given pages
|
|
|
|
*
|
2021-11-04 21:19:59 +00:00
|
|
|
* @param array $pagesByPageId key-value array where key is pageID and value is Title
|
2020-04-20 13:34:12 +00:00
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
private function getFileNamesForPageTitles( $pagesByPageId ): array {
|
|
|
|
$propValues = $this->pageProps->getProperties(
|
|
|
|
$pagesByPageId,
|
|
|
|
PageImages::getPropNames( PageImages::LICENSE_ANY )
|
|
|
|
);
|
2021-05-12 09:23:38 +00:00
|
|
|
$fileNames = array_map( static function ( $prop ) {
|
2020-04-20 13:34:12 +00:00
|
|
|
return $prop[ PageImages::getPropName( false ) ]
|
|
|
|
?? $prop[ PageImages::getPropName( true ) ]
|
|
|
|
?? null;
|
|
|
|
}, $propValues );
|
|
|
|
|
2021-05-12 09:23:38 +00:00
|
|
|
return array_filter( $fileNames, static function ( $fileName ) {
|
2020-04-20 13:34:12 +00:00
|
|
|
return $fileName != null;
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a list fileNames for with given LinkTarget, where title is NS_FILE
|
|
|
|
*
|
2021-11-04 21:19:59 +00:00
|
|
|
* @param array $linkFileTargetsByPageId key-value array of where key
|
2020-04-20 13:34:12 +00:00
|
|
|
* is pageId, value is LinkTarget
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
private function getFileNamesForFileTitles( $linkFileTargetsByPageId ): array {
|
2021-05-12 09:23:38 +00:00
|
|
|
return array_map( static function ( $linkFileTarget ) {
|
2020-04-20 13:34:12 +00:00
|
|
|
return $linkFileTarget->getDBkey();
|
|
|
|
}, $linkFileTargetsByPageId );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns thumbnails for given list
|
|
|
|
*
|
|
|
|
* @param array $titlesByPageId a key value array where key is pageId and value is Title
|
2020-07-07 07:44:45 +00:00
|
|
|
* @param int $size size of thumbnail height and width in points
|
2021-05-04 14:51:18 +00:00
|
|
|
* @return SearchResultThumbnail[]
|
2020-04-20 13:34:12 +00:00
|
|
|
*/
|
2020-07-07 07:44:45 +00:00
|
|
|
private function getThumbnails( array $titlesByPageId, int $size ): array {
|
2021-05-12 09:23:38 +00:00
|
|
|
$pagesByPageId = array_filter( $titlesByPageId, static function ( $title ) {
|
2020-04-20 13:34:12 +00:00
|
|
|
return !$title->inNamespace( NS_FILE );
|
|
|
|
} );
|
2021-05-12 09:23:38 +00:00
|
|
|
$titleFilesByPageId = array_filter( $titlesByPageId, static function ( $title ) {
|
2020-04-20 13:34:12 +00:00
|
|
|
return $title->inNamespace( NS_FILE );
|
|
|
|
} );
|
|
|
|
|
|
|
|
$files = $this->getFileNamesForPageTitles( $pagesByPageId )
|
|
|
|
+ $this->getFileNamesForFileTitles( $titleFilesByPageId );
|
|
|
|
|
|
|
|
$res = [];
|
|
|
|
foreach ( $files as $pageId => $fileName ) {
|
|
|
|
$file = $this->repoGroup->findFile( $fileName );
|
|
|
|
if ( !$file ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$thumb = $file->transform( [ 'width' => $size , 'height' => $size ] );
|
2021-09-14 16:56:05 +00:00
|
|
|
if ( !$thumb || $thumb->isError() ) {
|
2020-04-20 13:34:12 +00:00
|
|
|
continue;
|
|
|
|
}
|
2020-05-07 16:29:51 +00:00
|
|
|
|
|
|
|
$localPath = $thumb->getLocalCopyPath();
|
|
|
|
$thumbSize = $localPath && file_exists( $localPath ) ? filesize( $localPath ) : null;
|
2020-04-20 13:34:12 +00:00
|
|
|
|
|
|
|
$res[$pageId] = new SearchResultThumbnail(
|
|
|
|
$thumb->getFile()->getMimeType(),
|
|
|
|
$thumbSize,
|
|
|
|
$thumb->getWidth(),
|
|
|
|
$thumb->getHeight(),
|
|
|
|
null,
|
|
|
|
wfExpandUrl( $thumb->getUrl(), PROTO_RELATIVE ),
|
|
|
|
$fileName
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param array $pageIdentities array that contain $pageId => SearchResultPageIdentity.
|
|
|
|
* @param array &$results Placeholder for result. $pageId => SearchResultThumbnail
|
2022-08-23 12:03:45 +00:00
|
|
|
* @param int|null $size size of thumbnail height and width in points
|
2020-04-20 13:34:12 +00:00
|
|
|
*/
|
2022-08-23 12:03:45 +00:00
|
|
|
public function onSearchResultProvideThumbnail( array $pageIdentities, &$results, int $size = null ): void {
|
2021-05-14 23:16:41 +00:00
|
|
|
$pageIdTitles = array_map( static function ( PageIdentity $identity ) {
|
2020-04-20 13:34:12 +00:00
|
|
|
return Title::makeTitle( $identity->getNamespace(), $identity->getDBkey() );
|
|
|
|
}, $pageIdentities );
|
|
|
|
|
2022-08-23 12:03:45 +00:00
|
|
|
$data = $this->getThumbnails( $pageIdTitles, $size ?? self::THUMBNAIL_SIZE );
|
2020-04-20 13:34:12 +00:00
|
|
|
foreach ( $data as $pageId => $thumbnail ) {
|
|
|
|
$results[ $pageId ] = $thumbnail;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|