Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
75.76% covered (warning)
75.76%
25 / 33
57.14% covered (warning)
57.14%
4 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
MediaInfoContent
75.76% covered (warning)
75.76%
25 / 33
57.14% covered (warning)
57.14%
4 / 7
14.05
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 emptyContent
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 getIgnoreKeysForFilters
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 getMediaInfo
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 getEntity
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getEntityHolder
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTextForSearchIndex
75.00% covered (warning)
75.00%
6 / 8
0.00% covered (danger)
0.00%
0 / 1
3.14
1<?php
2
3namespace Wikibase\MediaInfo\Content;
4
5use InvalidArgumentException;
6use LogicException;
7use MediaWiki\MediaWikiServices;
8use Wikibase\MediaInfo\DataModel\MediaInfo;
9use Wikibase\Repo\Content\EntityContent;
10use Wikibase\Repo\Content\EntityHolder;
11use Wikibase\Repo\FingerprintSearchTextGenerator;
12
13/**
14 * @license GPL-2.0-or-later
15 * @author Bene* < benestar.wikimedia@gmail.com >
16 */
17class MediaInfoContent extends EntityContent {
18
19    public const CONTENT_MODEL_ID = 'wikibase-mediainfo';
20
21    /**
22     * @var EntityHolder|null
23     */
24    private $mediaInfoHolder;
25
26    /**
27     * Do not use to construct new stuff from outside of this class,
28     * use the static newFoobar methods.
29     *
30     * In other words: treat as protected (which it was, but now
31     * cannot be since we derive from Content).
32     *
33     * @protected
34     *
35     * @param EntityHolder|null $mediaInfoHolder
36     * @throws InvalidArgumentException
37     */
38    public function __construct( EntityHolder $mediaInfoHolder = null ) {
39        parent::__construct( self::CONTENT_MODEL_ID );
40
41        if ( $mediaInfoHolder !== null
42            && $mediaInfoHolder->getEntityType() !== MediaInfo::ENTITY_TYPE
43        ) {
44            throw new InvalidArgumentException( '$mediaInfoHolder must contain a MediaInfo entity' );
45        }
46
47        $this->mediaInfoHolder = $mediaInfoHolder;
48    }
49
50    /**
51     * Constructs an empty content object.
52     *
53     * @return MediaInfoContent
54     */
55    public static function emptyContent(): MediaInfoContent {
56        return new self( new class() implements EntityHolder {
57
58            public function getEntity( $expectedClass = MediaInfo::class ) {
59                return new MediaInfo();
60            }
61
62            public function getEntityId() {
63                return null;
64            }
65
66            public function getEntityType() {
67                return MediaInfo::ENTITY_TYPE;
68            }
69
70        } );
71    }
72
73    protected function getIgnoreKeysForFilters() {
74        // We explicitly want to allow the 'labels' block's 'language' keys through, so that AbuseFilters
75        // can be written that check if e.g. Latin characters are written in a zh-hans label slot.
76        return [
77            // pageid, ns, title, lastrevid, & modified are injected in the API but not AF, so don't list
78            // MediaInfo entities don't have a "site" attribute, so this shouldn't show up, but for safety
79            'site',
80            // MediaInfo is not going to use descriptions but they currently appear in the
81            // serialization. These should not be checked for filter text.
82            'descriptions',
83            // Probably won't be used, could be added back if requested
84            'rank',
85            // Options: value, somevalue, novalue
86            'snaktype',
87            // Probably pointless in filter text
88            'hash',
89            // Statement guid
90            'id',
91            // Hits a few different things
92            'type',
93            // Hits a few different things
94            'datatype',
95        ];
96    }
97
98    /**
99     * @return MediaInfo
100     */
101    public function getMediaInfo() {
102        if ( !$this->mediaInfoHolder ) {
103            throw new LogicException( 'This content object is empty!' );
104        }
105
106        // @phan-suppress-next-line PhanTypeMismatchReturnSuperType
107        return $this->mediaInfoHolder->getEntity( MediaInfo::class );
108    }
109
110    /**
111     * @see EntityContent::getEntity
112     *
113     * @return MediaInfo
114     */
115    public function getEntity() {
116        return $this->getMediaInfo();
117    }
118
119    /**
120     * @see EntityContent::getEntityHolder
121     *
122     * @return EntityHolder|null
123     */
124    public function getEntityHolder() {
125        return $this->mediaInfoHolder;
126    }
127
128    /**
129     * @see EntityContent::getTextForSearchIndex
130     *
131     * @return string
132     */
133    public function getTextForSearchIndex() {
134        if ( $this->isRedirect() ) {
135            return '';
136        }
137
138        $searchTextGenerator = new FingerprintSearchTextGenerator();
139        $text = $searchTextGenerator->generate( $this->getMediaInfo() );
140
141        if ( !MediaWikiServices::getInstance()->getHookContainer()
142            ->run( 'WikibaseTextForSearchIndex', [ $this, &$text ] )
143        ) {
144            return '';
145        }
146
147        return $text;
148    }
149
150}