Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
76.09% covered (warning)
76.09%
35 / 46
50.00% covered (danger)
50.00%
5 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
GLTFHandler
76.09% covered (warning)
76.09%
35 / 46
50.00% covered (danger)
50.00%
5 / 10
22.43
0.00% covered (danger)
0.00%
0 / 1
 getSizeAndMetadata
76.19% covered (warning)
76.19%
16 / 21
0.00% covered (danger)
0.00%
0 / 1
6.49
 verifyUpload
90.91% covered (success)
90.91%
10 / 11
0.00% covered (danger)
0.00%
0 / 1
2.00
 isFileMetadataValid
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 normaliseParams
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 mustRender
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getParamMap
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 validateParam
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 makeParamString
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 parseParamString
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 doTransform
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace MediaWiki\Extension\GLTFHandler;
4
5use InvalidArgumentException;
6use MediaWiki\Extension\GLTFHandler\Parser\GLTFParser;
7use MediaWiki\Status\Status;
8use function is_numeric;
9use function max;
10use function preg_match;
11
12class GLTFHandler extends \MediaHandler {
13
14    /** @inheritDoc */
15    public function getSizeAndMetadata( $state, $path ) {
16        global $wgGLTFHandlerMaxAccessorValues;
17        try {
18            $parser = new GLTFParser( $path, max_accessor_values: $wgGLTFHandlerMaxAccessorValues );
19            $dims = $parser->computeModelDimensions();
20        } catch ( InvalidArgumentException ) {
21            return null;
22        }
23        if ( $dims === null ) {
24            return null;
25        }
26        $width = max( $dims[0], $dims[2] );
27        $height = $dims[1];
28
29        // normalize size
30        $f = $width + $height;
31        if ( $f <= 0 ) {
32            return null;
33        }
34        $width /= $f;
35        $height /= $f;
36
37        $width *= 400;
38        $height *= 400;
39
40        $metadata = [ "version" => $parser->version ];
41        if ( $parser->copyright !== null ) {
42            $metadata["copyright"] = $parser->copyright;
43        }
44        if ( $parser->generator !== null ) {
45            $metadata["generator"] = $parser->generator;
46        }
47        return [ "width" => $width, "height" => $height, "metadata" => $metadata ];
48    }
49
50    /** @inheritDoc */
51    public function verifyUpload( $fileName ) {
52        global $wgGLTFHandlerMaxAccessorValues;
53        try {
54            // Constructor validation is the purpose of this instantiation.
55            // @phan-suppress-next-line PhanNoopNew
56            new GLTFParser( $fileName, max_accessor_values: $wgGLTFHandlerMaxAccessorValues );
57        } catch ( InvalidArgumentException $e ) {
58            return Status::newFatal( match ( $e->getCode() ) {
59                GLTFParser::ERR_UNSUPPORTED_VERSION => "gltfhandler-error-unsupportedversion",
60                GLTFParser::ERR_INVALID_SCHEMA => "gltfhandler-error-invalidschema",
61                GLTFParser::ERR_URI_RESOLUTION_EMBEDDED => "gltfhandler-error-uriresolutionembedded",
62                GLTFParser::ERR_URI_RESOLUTION_LOCAL => "gltfhandler-error-uriresolutionlocal",
63                GLTFParser::ERR_URI_RESOLUTION_REMOTE => "gltfhandler-error-uriresolutionremote",
64                default => "gltfhandler-error-unknown"
65            } );
66        }
67        return parent::verifyUpload( $fileName );
68    }
69
70    /** @inheritDoc */
71    public function isFileMetadataValid( $image ) {
72        if ( $image->getMetadataItem( "Version" ) === null ) {
73            return self::METADATA_BAD;
74        }
75        return self::METADATA_GOOD;
76    }
77
78    /** @inheritDoc */
79    public function normaliseParams( $image, &$params ) {
80        return true;
81    }
82
83    /** @inheritDoc */
84    public function mustRender( $file ) {
85        return true;
86    }
87
88    /** @inheritDoc */
89    public function getParamMap() {
90        return array_column( Constants::PARAMS, "name", "magic_word_id" );
91    }
92
93    /** @inheritDoc */
94    public function validateParam( $name, $value ) {
95        return match ( $name ) {
96            "width", "height" => $value > 0,
97            "skybox-height" => is_numeric( $value ) || preg_match( '/\s*([0-9.]+)\s*(mm|m|cm)/m', $value ) > 0,
98            default => true
99        };
100    }
101
102    /** @inheritDoc */
103    public function makeParamString( $params ) {
104        return bin2hex( json_encode( $params ) );
105    }
106
107    /** @inheritDoc */
108    public function parseParamString( $str ) {
109        return json_decode( hex2bin( $str ), true );
110    }
111
112    /**
113     * @inheritDoc
114     */
115    public function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) {
116        return new GLTFTransformOutput( $image, $image->getWidth(), $image->getHeight(), $params );
117    }
118}