Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.92% covered (success)
97.92%
47 / 48
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Popup
97.92% covered (success)
97.92%
47 / 48
75.00% covered (warning)
75.00%
3 / 4
9
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 run
96.00% covered (success)
96.00%
24 / 25
0.00% covered (danger)
0.00%
0 / 1
5
 buildHTMLRepresentation
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
2
 getParamSettings
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace MediaWiki\Extension\Math\Rest;
4
5use MediaWiki\Extension\Math\MathWikibaseConnector;
6use MediaWiki\Extension\Math\MathWikibaseInfo;
7use MediaWiki\Html\Html;
8use MediaWiki\Language\LanguageFactory;
9use MediaWiki\Language\LanguageNameUtils;
10use MediaWiki\Rest\Response;
11use MediaWiki\Rest\SimpleHandler;
12use MediaWiki\Title\Title;
13use MediaWiki\Title\TitleFactory;
14use Wikimedia\ParamValidator\ParamValidator;
15
16class Popup extends SimpleHandler {
17
18    /** @var Title|null */
19    private $specialPageTitle;
20
21    public function __construct(
22        private readonly MathWikibaseConnector $wikibase,
23        private readonly LanguageFactory $languageFactory,
24        private readonly LanguageNameUtils $languageNameUtils,
25        TitleFactory $titleFactory,
26    ) {
27        $this->specialPageTitle = $titleFactory->newFromText( 'Special:MathWikibase' );
28    }
29
30    public function run( int $qid ): Response {
31        $uselang = $this->getRequest()->getHeaderLine( 'Accept-Language' );
32        if ( $uselang === '' ) {
33            $uselang = 'en';
34        }
35        $rf = $this->getResponseFactory();
36        if ( $this->languageNameUtils->isValidCode( $uselang ) ) {
37            $langObj = $this->languageFactory->getLanguage( $uselang );
38        } else {
39            return $rf->createHttpError( 400, [ 'message' => 'Invalid language code.' ] );
40        }
41
42        try {
43            $info = $this->wikibase->fetchWikibaseFromId( "Q{$qid}", $uselang );
44        } catch ( \InvalidArgumentException $exception ) {
45            return $rf->createHttpError( 400, [ 'message' => $exception->getMessage() ] );
46        }
47
48        $html = $this->buildHTMLRepresentation( $info );
49
50        $response = [
51            'title' => $info->getLabel(),
52            'contentmodel' => 'html',
53            'pagelanguagedir' => $langObj->getDir(),
54            'pagelanguage' => $langObj->getCode(),
55            'pagelanguagehtmlcode' => $langObj->getHtmlCode(),
56            'extract' => $html
57        ];
58
59        if ( $this->specialPageTitle ) {
60            $response = array_merge( $response, [
61                'canonicalurl' => $this->specialPageTitle->getLocalURL( [ 'qid' => "Q{$qid}" ] ),
62                'fullurl' => $this->specialPageTitle->getFullURL( [ 'qid' => "Q{$qid}" ] )
63            ] );
64        }
65
66        return $rf->createJson( $response );
67    }
68
69    /**
70     * Generates an HTML string from the given data.
71     * @param MathWikibaseInfo $info an info object generated by fetchWikibaseFromId
72     * @return string an HTML representation of the given info object
73     */
74    private function buildHTMLRepresentation( MathWikibaseInfo $info ): string {
75        $output =
76            Html::openElement( "div",
77                [ "style" =>
78                    "width: 100%; display: flex; flex-direction: column;
79                    align-items: flex-start; flex-wrap: wrap;" ] );
80        $output .= Html::element( "span", [
81            "style" => "font-weight: bold; text-transform: capitalize;"
82        ], $info->getLabel() );
83        $output .= Html::element( "span", [ "style" => "font-size: small" ], " (" . $info->getDescription() . ")" );
84        if ( $info->hasParts() ) {
85            $output .= Html::rawElement( "div",
86                [ "style" => "width: 100%; display: flex; justify-content: left; padding-top: 5px;" ],
87                $info->generateSmallTableOfParts() );
88        }
89        $output .= Html::closeElement( "div" );
90
91        return $output;
92    }
93
94    public function getParamSettings(): array {
95        return [
96            'qid' => [
97                self::PARAM_SOURCE => 'path',
98                ParamValidator::PARAM_TYPE => 'integer',
99                ParamValidator::PARAM_REQUIRED => true
100            ]
101        ];
102    }
103}