Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
58.97% covered (warning)
58.97%
23 / 39
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
SearchResultThumbnailProvider
58.97% covered (warning)
58.97%
23 / 39
0.00% covered (danger)
0.00%
0 / 4
14.59
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getFileNamesByPageId
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
2
 buildSearchResultThumbnailFromFile
92.86% covered (success)
92.86%
13 / 14
0.00% covered (danger)
0.00%
0 / 1
3.00
 getThumbnails
90.91% covered (success)
90.91%
10 / 11
0.00% covered (danger)
0.00%
0 / 1
4.01
1<?php
2
3namespace MediaWiki\Search;
4
5use File;
6use MediaWiki\HookContainer\HookContainer;
7use MediaWiki\HookContainer\HookRunner;
8use MediaWiki\MediaWikiServices;
9use MediaWiki\Page\PageIdentity;
10use MediaWiki\Search\Entity\SearchResultThumbnail;
11use RepoGroup;
12
13/**
14 * Find thumbnails for search results
15 *
16 * @since 1.40
17 */
18class SearchResultThumbnailProvider {
19
20    public const THUMBNAIL_SIZE = 60;
21
22    private RepoGroup $repoGroup;
23    private HookRunner $hookRunner;
24
25    public function __construct( RepoGroup $repoGroup, HookContainer $hookContainer ) {
26        $this->repoGroup = $repoGroup;
27        $this->hookRunner = new HookRunner( $hookContainer );
28    }
29
30    /**
31     * Returns a list of fileNames for a given list of PageIdentity objects (within NS_FILE)
32     *
33     * @param PageIdentity[] $identitiesByPageId key-value array of where key
34     *   is pageId, value is PageIdentity
35     * @return array
36     */
37    private function getFileNamesByPageId( array $identitiesByPageId ): array {
38        $fileIdentitiesByPageId = array_filter(
39            $identitiesByPageId,
40            static function ( PageIdentity $pageIdentity ) {
41                return $pageIdentity->getNamespace() === NS_FILE;
42            }
43        );
44
45        return array_map(
46            static function ( PageIdentity $pageIdentity ) {
47                return $pageIdentity->getDBkey();
48            },
49            $fileIdentitiesByPageId
50        );
51    }
52
53    /**
54     * Returns a SearchResultThumbnail instance for a given File/size combination.
55     *
56     * @param File $file
57     * @param int|null $size
58     * @return SearchResultThumbnail|null
59     */
60    public function buildSearchResultThumbnailFromFile( File $file, ?int $size = null ): ?SearchResultThumbnail {
61        $size ??= self::THUMBNAIL_SIZE;
62
63        $thumb = $file->transform( [ 'width' => $size ] );
64        if ( !$thumb || $thumb->isError() ) {
65            return null;
66        }
67
68        $urlUtils = MediaWikiServices::getInstance()->getUrlUtils();
69        return new SearchResultThumbnail(
70            $thumb->getFile()->getMimeType(),
71            null,
72            $thumb->getWidth(),
73            $thumb->getHeight(),
74            null,
75            $urlUtils->expand( $thumb->getUrl(), PROTO_RELATIVE ) ?? false,
76            $file->getName()
77        );
78    }
79
80    /**
81     * @param PageIdentity[] $pageIdentities array that contains $pageId => PageIdentity.
82     * @param int|null $size size of thumbnail height and width in points
83     * @return SearchResultThumbnail[] array of $pageId => SearchResultThumbnail
84     */
85    public function getThumbnails( array $pageIdentities, ?int $size = 60 ): array {
86        // add filenames for NS_FILE pages by default
87        $fileNamesByPageId = $this->getFileNamesByPageId( $pageIdentities );
88        $results = [];
89        foreach ( $fileNamesByPageId as $pageId => $fileName ) {
90            $file = $this->repoGroup->findFile( $fileName );
91            if ( !$file ) {
92                continue;
93            }
94            $thumbnail = $this->buildSearchResultThumbnailFromFile( $file, $size );
95            if ( $thumbnail ) {
96                $results[$pageId] = $thumbnail;
97            }
98        }
99
100        // allow extensions to inject additional thumbnails
101        $this->hookRunner->onSearchResultProvideThumbnail( $pageIdentities, $results, $size );
102
103        return $results;
104    }
105}