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