Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
SkinAfterBottomScriptsHandler
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
3 / 3
12
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getSchemaElement
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
5
 getSchema
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
6
1<?php
2
3namespace CommonsMetadata\Hooks;
4
5use File;
6use FormatMetadata;
7use MediaWiki\Html\Html;
8use MediaWiki\Title\Title;
9
10/**
11 * @license GPL-2.0-or-later
12 */
13class SkinAfterBottomScriptsHandler {
14    /** @var FormatMetadata */
15    private $format;
16
17    /** @var string */
18    private $publicDomainPageUrl;
19
20    /**
21     * @param FormatMetadata $format
22     * @param string $publicDomainPageUrl
23     */
24    public function __construct( $format, $publicDomainPageUrl ) {
25        $this->format = $format;
26        $this->publicDomainPageUrl = $publicDomainPageUrl;
27    }
28
29    /**
30     * @param Title $title Title of the file page
31     * @param File|null $file The file itself
32     *
33     * @return string
34     */
35    public function getSchemaElement( Title $title, $file ) {
36        $allowedMediaTypes = [ MEDIATYPE_BITMAP, MEDIATYPE_DRAWING ];
37        if ( $file === null || !$file->exists() || !in_array( $file->getMediaType(), $allowedMediaTypes ) ) {
38            return '';
39        }
40
41        $extendedMetadata = $this->format->fetchExtendedMetadata( $file );
42        $schema = $this->getSchema( $title, $file, $extendedMetadata );
43        if ( $schema === null ) {
44            return '';
45        }
46
47        $html = Html::openElement( 'script', [ 'type' => 'application/ld+json' ] );
48        $html .= json_encode( $schema );
49        $html .= Html::closeElement( 'script' );
50        return $html;
51    }
52
53    /**
54     * @param Title $title
55     * @param File $file
56     * @param array $extendedMetadata
57     *
58     * @return array|null
59     */
60    public function getSchema( Title $title, File $file, $extendedMetadata ) {
61        if ( isset( $extendedMetadata[ 'LicenseUrl' ] ) ) {
62            $licenseUrl = $extendedMetadata[ 'LicenseUrl' ][ 'value' ];
63        } elseif ( isset( $extendedMetadata[ 'License' ] ) &&
64            $extendedMetadata[ 'License' ][ 'value' ] === 'pd' ) {
65            // If an image is in the public domain, there is no license to link
66            // to, so we'll link to a page describing the use of such images.
67            $licenseUrl = $this->publicDomainPageUrl;
68        }
69
70        if ( !isset( $licenseUrl ) ) {
71            return null;
72        }
73
74        $schema = [
75            '@context' => 'https://schema.org',
76            '@type' => 'ImageObject',
77            // The original file, which is what's indexed by Google and present
78            // in Google image searches.
79            'contentUrl' => $file->getFullUrl(),
80            // A link to the actual license (or to the public domain page).
81            'license' => $licenseUrl,
82            // This is meant to be a human-readable summary of the license, so
83            // we're linking to the file page which contains such a summary in
84            // the Licensing section.
85            'acquireLicensePage' => $title->getFullURL(),
86        ];
87
88        if ( isset( $extendedMetadata[ 'DateTime' ] ) ) {
89            $schema[ 'uploadDate' ] = $extendedMetadata[ 'DateTime' ][ 'value' ];
90        }
91
92        return $schema;
93    }
94}