Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 52 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
ImageRecommendationMetadataService | |
0.00% |
0 / 52 |
|
0.00% |
0 / 4 |
132 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
getExtendedMetadata | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
getFileMetadata | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
20 | |||
getApiMetadata | |
0.00% |
0 / 26 |
|
0.00% |
0 / 1 |
20 |
1 | <?php |
2 | |
3 | namespace GrowthExperiments\NewcomerTasks\AddImage; |
4 | |
5 | use FormatMetadata; |
6 | use GrowthExperiments\Util; |
7 | use MediaTransformError; |
8 | use MediaWiki\Http\HttpRequestFactory; |
9 | use MediaWiki\Language\RawMessage; |
10 | use RepoGroup; |
11 | use StatusValue; |
12 | |
13 | /** |
14 | * Fetch and process metadata for image recommendation |
15 | */ |
16 | class ImageRecommendationMetadataService { |
17 | |
18 | /** @var int */ |
19 | private const THUMB_WIDTH = 120; |
20 | |
21 | /** @var HttpRequestFactory */ |
22 | private $httpRequestFactory; |
23 | |
24 | /** @var RepoGroup */ |
25 | private $repoGroup; |
26 | |
27 | /** @var string[] */ |
28 | private $mediaInfoRepos; |
29 | |
30 | /** @var string */ |
31 | private $contentLanguage; |
32 | |
33 | /** |
34 | * @param HttpRequestFactory $httpRequestFactory |
35 | * @param RepoGroup $repoGroup |
36 | * @param string[] $mediaInfoRepos List of repo names which provide WikibaseMediaInfo data. |
37 | * @param string $contentLanguage Language code of wiki content language |
38 | */ |
39 | public function __construct( |
40 | HttpRequestFactory $httpRequestFactory, |
41 | RepoGroup $repoGroup, |
42 | array $mediaInfoRepos, |
43 | $contentLanguage |
44 | ) { |
45 | $this->httpRequestFactory = $httpRequestFactory; |
46 | $this->repoGroup = $repoGroup; |
47 | $this->mediaInfoRepos = $mediaInfoRepos; |
48 | $this->contentLanguage = $contentLanguage; |
49 | } |
50 | |
51 | /** |
52 | * Fetch extended metadata for the current file |
53 | * |
54 | * @param string $fileName Image file name for which to fetch extended metadata. |
55 | * @return array|StatusValue On success, the extended metadata, as returned by |
56 | * FormatMetadata::fetchExtendedMetadata() |
57 | */ |
58 | public function getExtendedMetadata( string $fileName ) { |
59 | $file = $this->repoGroup->findFile( $fileName ); |
60 | if ( $file ) { |
61 | return ( new FormatMetadata )->fetchExtendedMetadata( $file ); |
62 | } |
63 | return StatusValue::newFatal( new RawMessage( 'Image file not found: $1', [ $fileName ] ) ); |
64 | } |
65 | |
66 | /** |
67 | * Get metadata for the specified image file name |
68 | * |
69 | * @param string $fileName |
70 | * @return array|StatusValue On success, an array of file metadata. See |
71 | * {@see ImageRecommendationMetadataProvider::getMetadata()} for details. |
72 | */ |
73 | public function getFileMetadata( string $fileName ) { |
74 | $file = $this->repoGroup->findFile( $fileName ); |
75 | if ( !$file ) { |
76 | return StatusValue::newFatal( new RawMessage( 'Image file not found: $1', [ $fileName ] ) ); |
77 | } else { |
78 | $thumb = $file->transform( [ 'width' => self::THUMB_WIDTH ] ); |
79 | if ( !$thumb ) { |
80 | return StatusValue::newFatal( 'rawmessage', 'Thumbnailing error' ); |
81 | } elseif ( $thumb instanceof MediaTransformError ) { |
82 | return StatusValue::newFatal( new RawMessage( 'Thumbnailing error: $1', [ $thumb->toText() ] ) ); |
83 | } |
84 | } |
85 | return [ |
86 | 'descriptionUrl' => $file->getDescriptionUrl(), |
87 | 'thumbUrl' => $thumb->getUrl(), |
88 | 'fullUrl' => $file->getUrl(), |
89 | 'originalWidth' => $file->getWidth(), |
90 | 'originalHeight' => $file->getHeight(), |
91 | 'mustRender' => $file->mustRender(), |
92 | 'isVectorized' => $file->isVectorized(), |
93 | 'mediaType' => $file->getMediaType() |
94 | ]; |
95 | } |
96 | |
97 | /** |
98 | * Get action=query API metadata for the specified image file name: |
99 | * - category data |
100 | * - pageterms (WikibaseMediaInfo) data (e.g. structured data on Commons) |
101 | * @param string $fileName |
102 | * @return array|StatusValue On success, an array of file metadata. See |
103 | * {@see ImageRecommendationMetadataProvider::getMetadata()} for details. |
104 | */ |
105 | public function getApiMetadata( string $fileName ) { |
106 | $file = $this->repoGroup->findFile( $fileName ); |
107 | if ( !$file ) { |
108 | return StatusValue::newFatal( new RawMessage( 'Image file not found: $1', [ $fileName ] ) ); |
109 | } |
110 | $repoName = $file->getRepoName(); |
111 | if ( !in_array( $repoName, $this->mediaInfoRepos, true ) ) { |
112 | return []; |
113 | } |
114 | $apiUrl = $file->getRepo()->makeUrl( '', 'api' ); |
115 | $status = Util::getApiUrl( $this->httpRequestFactory, $apiUrl, [ |
116 | 'action' => 'query', |
117 | // The File namespace name might be in a different language locally than on the |
118 | // repo wiki; in theory, even the canonical namespace name might be different as |
119 | // it's configurable. Just hardcode the standard name. |
120 | 'titles' => 'File:' . $file->getTitle()->getDBkey(), |
121 | 'prop' => 'categories|pageterms', |
122 | 'clshow' => '!hidden', |
123 | 'cllimit' => 'max', |
124 | 'wbptterms' => 'label', |
125 | 'wbptlanguage' => $this->contentLanguage, |
126 | ], true ); |
127 | if ( !$status->isOK() ) { |
128 | return $status; |
129 | } |
130 | $data = $status->getValue(); |
131 | |
132 | return [ |
133 | 'caption' => $data['query']['pages'][0]['terms']['label'][0] ?? null, |
134 | 'categories' => array_map( static function ( $categoryData ) { |
135 | $title = $categoryData['title']; |
136 | // strip namespace prefix |
137 | return explode( ':', $title, 2 )[1]; |
138 | }, $data['query']['pages'][0]['categories'] ?? [] ), |
139 | ]; |
140 | } |
141 | |
142 | } |