Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.16% covered (success)
95.16%
59 / 62
76.92% covered (warning)
76.92%
10 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
MediaInfoSpecificComponentsRdfBuilder
95.16% covered (success)
95.16%
59 / 62
76.92% covered (warning)
76.92%
10 / 13
26
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 addEntity
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 aboutId
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 addTypes
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addFileMetadataFromEntityId
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
3.03
 addFileMetadataFromFile
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
2
 addFileSpecificType
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getFileSpecificType
88.89% covered (warning)
88.89%
8 / 9
0.00% covered (danger)
0.00%
0 / 1
6.05
 addEncodingFormat
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 addFileUrl
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 addFileUrlAlt
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 addDuration
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 addPositiveIntegerValue
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3namespace Wikibase\MediaInfo\Rdf;
4
5use File;
6use RepoGroup;
7use Wikibase\DataModel\Entity\EntityDocument;
8use Wikibase\MediaInfo\Content\MediaInfoHandler;
9use Wikibase\MediaInfo\DataModel\MediaInfo;
10use Wikibase\MediaInfo\DataModel\MediaInfoId;
11use Wikibase\Repo\Rdf\EntityRdfBuilder;
12use Wikibase\Repo\Rdf\RdfVocabulary;
13use Wikimedia\Purtle\RdfWriter;
14
15/**
16 * RDF builder for MediaInfo
17 */
18class MediaInfoSpecificComponentsRdfBuilder implements EntityRdfBuilder {
19
20    /**
21     * @var RdfVocabulary
22     */
23    private $vocabulary;
24
25    /**
26     * @var RdfWriter
27     */
28    private $writer;
29
30    /**
31     * @var MediaInfoHandler
32     */
33    private $mediaInfoHandler;
34
35    /**
36     * @var RepoGroup
37     */
38    private $repoGroup;
39
40    public function __construct(
41        RdfVocabulary $vocabulary,
42        RdfWriter $writer,
43        MediaInfoHandler $mediaInfoHandler,
44        RepoGroup $repoGroup
45    ) {
46        $this->vocabulary = $vocabulary;
47        $this->writer = $writer;
48        $this->mediaInfoHandler = $mediaInfoHandler;
49        $this->repoGroup = $repoGroup;
50    }
51
52    /**
53     * Map some aspect of an Entity to the RDF graph.
54     *
55     * @param EntityDocument $entity the entity to output.
56     */
57    public function addEntity( EntityDocument $entity ) {
58        if ( !$entity instanceof MediaInfo ) {
59            return;
60        }
61
62        $this->addTypes( $entity->getId() );
63        $this->addFileMetadataFromEntityId( $entity->getId() );
64    }
65
66    /**
67     * Start an "about" clause for the given ID in the RDF writer.
68     *
69     * @param MediaInfoId $id
70     * @return RDFWriter for chaining
71     */
72    private function aboutId( MediaInfoId $id ): RdfWriter {
73        $mediaLName = $this->vocabulary->getEntityLName( $id );
74
75        $mediaRepository = $this->vocabulary->getEntityRepositoryName( $id );
76
77        return $this->writer->about( $this->vocabulary->entityNamespaceNames[$mediaRepository], $mediaLName );
78    }
79
80    /**
81     * Produce MediaInfo types
82     * @param MediaInfoId $id
83     */
84    private function addTypes( MediaInfoId $id ) {
85        $this->aboutId( $id )
86            ->a( RdfVocabulary::NS_SCHEMA_ORG, 'MediaObject' );
87    }
88
89    /**
90     * Add file metadata to RDF representation
91     *
92     * @param MediaInfoId $id
93     */
94    private function addFileMetadataFromEntityId( MediaInfoId $id ) {
95        $fileTitle = $this->mediaInfoHandler->getTitleForId( $id );
96        if ( $fileTitle === null ) {
97            return;
98        }
99        $file = $this->repoGroup->findFile( $fileTitle );
100        if ( $file === false ) {
101            return;
102        }
103        $this->addFileMetadataFromFile( $id, $file );
104    }
105
106    private function addFileMetadataFromFile( MediaInfoId $id, File $file ) {
107        $this->addFileSpecificType( $id, $file );
108        $this->addEncodingFormat( $id, $file );
109        $this->addFileUrl( $id, $file );
110        $this->addFileUrlAlt( $id, $file );
111
112        $this->addPositiveIntegerValue( $id, 'contentSize', $file->getSize() );
113        if ( $file->isMultipage() ) {
114            $this->addPositiveIntegerValue( $id, 'numberOfPages', $file->pageCount() );
115            // Width and height of a file is not always the same for all pages of multi-pages files
116        } else {
117            $this->addPositiveIntegerValue( $id, 'height', $file->getHeight() );
118            $this->addPositiveIntegerValue( $id, 'width', $file->getWidth() );
119        }
120        $this->addDuration( $id, $file );
121    }
122
123    private function addFileSpecificType( MediaInfoId $id, File $file ) {
124        $specificType = $this->getFileSpecificType( $file );
125        if ( $specificType !== null ) {
126            $this->aboutId( $id )
127                ->a( RdfVocabulary::NS_SCHEMA_ORG, $specificType );
128        }
129    }
130
131    private function getFileSpecificType( File $file ) {
132        switch ( $file->getMediaType() ) {
133            case MEDIATYPE_BITMAP:
134            case MEDIATYPE_DRAWING:
135                return 'ImageObject';
136            case MEDIATYPE_AUDIO:
137                return 'AudioObject';
138            case MEDIATYPE_VIDEO:
139                return 'VideoObject';
140            default:
141                return null;
142        }
143    }
144
145    private function addEncodingFormat( MediaInfoId $id, File $file ) {
146        $this->aboutId( $id )
147            ->say( RdfVocabulary::NS_SCHEMA_ORG, 'encodingFormat' )
148            ->value( $file->getMimeType() );
149    }
150
151    private function addFileUrl( MediaInfoId $id, File $file ) {
152        $this->aboutId( $id )
153            ->say( RdfVocabulary::NS_SCHEMA_ORG, 'contentUrl' )
154            ->is( $file->getCanonicalUrl() );
155    }
156
157    private function addFileUrlAlt( MediaInfoId $id, File $file ) {
158        $url = $this->vocabulary->getMediaFileURI( $file->getTitle()->getText() );
159
160        $this->aboutId( $id )
161            ->say( RdfVocabulary::NS_SCHEMA_ORG, 'url' )
162            ->is( $url );
163    }
164
165    private function addDuration( MediaInfoId $id, File $file ) {
166        $duration = $file->getLength();
167        if ( $duration > 0 ) {
168            $this->aboutId( $id )
169                ->say( RdfVocabulary::NS_SCHEMA_ORG, 'duration' )
170                ->value( 'PT' . $duration . 'S', 'xsd', 'duration' );
171        }
172    }
173
174    private function addPositiveIntegerValue( MediaInfoId $id, $schemaProperty, $value ) {
175        if ( is_int( $value ) && $value > 0 ) {
176            $this->aboutId( $id )
177                ->say( RdfVocabulary::NS_SCHEMA_ORG, $schemaProperty )
178                ->value( (string)$value, 'xsd', 'integer' );
179        }
180    }
181}