Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
63.33% covered (warning)
63.33%
19 / 30
77.78% covered (warning)
77.78%
7 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
ImageRecommendationImage
63.33% covered (warning)
63.33%
19 / 30
77.78% covered (warning)
77.78%
7 / 9
12.99
0.00% covered (danger)
0.00%
0 / 1
 fromArray
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 getImageTitle
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSource
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getProjects
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSectionNumber
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSectionTitle
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 toArray
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
 jsonSerialize
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace GrowthExperiments\NewcomerTasks\AddImage;
4
5use JsonSerializable;
6use MediaWiki\Linker\LinkTarget;
7use MediaWiki\Title\TitleValue;
8
9/**
10 * Represents an individual suggested image within an ImageRecommendation.
11 */
12class ImageRecommendationImage implements JsonSerializable {
13
14    /**
15     * The recommendation is based on the image property (P18 or similar) of the
16     * linked Wikidata item.
17     */
18    public const SOURCE_WIKIDATA = 'wikidata';
19    /**
20     * The recommendation is based on images used in other language versions of the article.
21     */
22    public const SOURCE_WIKIPEDIA = 'wikipedia';
23    /**
24     * The recommendation is based on the Wikimedia Commons category referenced in the
25     * linked Wikidata item (via the P373 property).
26     */
27    public const SOURCE_COMMONS = 'commons';
28    /**
29     * The recommendation is based on the image property (P18 or similar) of a
30     * Wikidata item that has been guessed by analyzing the text of an article section.
31     */
32    public const SOURCE_WIKIDATA_SECTION_TOPICS = 'wikidata-section-topics';
33    /**
34     * The recommendation is based on another language version of the article using the
35     * image in the same section (where "same section" is being defined as the Wikidata
36     * items guessed by analyzing the text of the sections having significant overlap).
37     */
38    public const SOURCE_WIKIDATA_SECTION_ALIGNMENT = 'wikidata-section-alignment';
39    /**
40     * The recommendation is based on both section topics and section alignment.
41     */
42    public const SOURCE_WIKIDATA_SECTION_INTERSECTION = 'wikidata-section-intersection';
43
44    public const KNOWN_SOURCES = [
45        self::SOURCE_WIKIDATA,
46        self::SOURCE_WIKIPEDIA,
47        self::SOURCE_COMMONS,
48        self::SOURCE_WIKIDATA_SECTION_TOPICS,
49        self::SOURCE_WIKIDATA_SECTION_ALIGNMENT,
50        self::SOURCE_WIKIDATA_SECTION_INTERSECTION,
51    ];
52
53    /**
54     * Maps deprecated source names to their current equivalents.
55     */
56    public const SOURCE_ALIASES = [
57        'wikidata-section' => self::SOURCE_WIKIDATA_SECTION_TOPICS,
58    ];
59
60    private LinkTarget $imageTitle;
61    private string $source;
62    /** @var string[] */
63    private array $projects;
64    private array $metadata;
65    private ?int $sectionNumber;
66    private ?string $sectionTitle;
67
68    /**
69     * Create an ImageRecommendationImage object from an array representation.
70     * This is the inverse of toArray().
71     * @param array $imageData
72     * @return ImageRecommendationImage
73     */
74    public static function fromArray( array $imageData ): ImageRecommendationImage {
75        return new ImageRecommendationImage(
76            new TitleValue( NS_FILE, $imageData['image'] ),
77            $imageData['source'],
78            $imageData['projects'] ?? [],
79            $imageData['metadata'] ?? [],
80            $imageData['sectionNumber'] ?? null,
81            $imageData['sectionTitle'] ?? null
82        );
83    }
84
85    /**
86     * @param LinkTarget $imageTitle The recommended image.
87     * @param string $source One of the SOURCE_* constants.
88     * @param string[] $projects List of projects (as wiki IDs) the recommendation was based on.
89     *   Only for SOURCE_INTERWIKI.
90     * @param array $metadata Metadata for the recommended image.
91     * @param int|null $sectionNumber Section number for which the image is recommended (1-based
92     *   index of the section within the second-level sections), or null for top-level
93     *   recommendations.
94     * @param string|null $sectionTitle Wikitext of the section title for which the image is
95     *   recommended, or null for top-level recommendations.
96     */
97    public function __construct(
98        LinkTarget $imageTitle,
99        string $source,
100        array $projects = [],
101        array $metadata = [],
102        ?int $sectionNumber = null,
103        ?string $sectionTitle = null
104    ) {
105        $this->imageTitle = $imageTitle;
106        $this->source = $source;
107        $this->projects = $projects;
108        $this->metadata = $metadata;
109        $this->sectionNumber = $sectionNumber;
110        $this->sectionTitle = $sectionTitle;
111    }
112
113    /**
114     * Get the recommended image.
115     * @return LinkTarget
116     */
117    public function getImageTitle(): LinkTarget {
118        return $this->imageTitle;
119    }
120
121    /**
122     * Get the information source the recommendation was based on.
123     * @return string One of the SOURCE_* constants.
124     */
125    public function getSource(): string {
126        return $this->source;
127    }
128
129    /**
130     * Get the list of projects the recommendation was based on. This only makes sense when
131     * getSource() is SOURCE_INTERWIKI, and will be an empty array otherwise.
132     * @return string[] List of wiki IDs.
133     */
134    public function getProjects(): array {
135        return $this->projects;
136    }
137
138    /**
139     * Section number for which the image is recommended (1-based index of the section within
140     * the second-level sections), or null for top-level recommendations.
141     * @return int|null
142     */
143    public function getSectionNumber(): ?int {
144        return $this->sectionNumber;
145    }
146
147    /**
148     * Wikitext of the section title for which the image is recommended, or null for top-level
149     * recommendations.
150     * @return string|null
151     */
152    public function getSectionTitle(): ?string {
153        return $this->sectionTitle;
154    }
155
156    /**
157     * @return array
158     */
159    public function toArray(): array {
160        $filename = $this->imageTitle->getDBkey();
161        return [
162            'image' => $filename,
163            'displayFilename' => str_replace( '_', ' ', $filename ),
164            'source' => $this->source,
165            'projects' => $this->projects,
166            'metadata' => $this->metadata,
167            'sectionNumber' => $this->sectionNumber,
168            'sectionTitle' => $this->sectionTitle,
169        ];
170    }
171
172    /** @inheritDoc */
173    public function jsonSerialize(): array {
174        return $this->toArray();
175    }
176}