mediawiki-extensions-Math/src/SpecialMathWikibase.php

247 lines
6.8 KiB
PHP
Raw Normal View History

<?php
use MediaWiki\Extension\Math\Widget\WikibaseEntitySelector;
use MediaWiki\Logger\LoggerFactory;
class SpecialMathWikibase extends SpecialPage {
/**
* The parameter for this special page
*/
private const PARAMETER = "qid";
/**
* @var MathWikibaseConnector Wikibase connection
*/
private $wikibase;
/**
* @var \Psr\Log\LoggerInterface
*/
private $logger;
public function __construct() {
parent::__construct( 'MathWikibase' );
$this->logger = LoggerFactory::getInstance( 'Math' );
}
/**
* @inheritDoc
*/
public function execute( $par ) {
global $wgLanguageCode;
if ( !$this->isWikibaseAvailable() ) {
$out = $this->getOutput();
$out->setPageTitle(
$this->getPlainText( 'math-wikibase-special-error-header' )
);
$out->addHTML(
$this->msg( 'math-wikibase-special-error-no-wikibase' )->inContentLanguage()->parse()
);
return;
}
if ( !$this->wikibase ) {
$this->wikibase = new MathWikibaseConnector(
MathWikibaseConfig::getDefaultMathWikibaseConfig()
);
}
$request = $this->getRequest();
$output = $this->getOutput();
$output->enableOOUI();
$this->setHeaders();
$output->addModules( [ 'mw.widgets.MathWbEntitySelector' ] );
$output->setPageTitle(
$this->getPlainText( 'math-wikibase-header' )
);
// Get request
$requestId = $request->getText( self::PARAMETER, $par );
// if there is no id requested, show the request form
if ( !$requestId ) {
$this->showForm();
} else {
$this->logger->debug( "Request qID: " . $requestId );
try {
$info = $this->wikibase->fetchWikibaseFromId( $requestId, $wgLanguageCode );
$this->logger->debug( "Successfully fetched information for qID: " . $requestId );
self::buildPageRepresentation( $info, $requestId, $output );
} catch ( Exception $e ) {
$this->showError( $e );
}
}
}
/**
* Shows the form to request information for a specific Wikibase id
*/
private function showForm() {
$actionField = new \OOUI\ActionFieldLayout(
new WikibaseEntitySelector( [
'name' => self::PARAMETER,
'placeholder' => $this->getPlainText( 'math-wikibase-special-form-placeholder' ),
'required' => true,
'infusable' => true,
'id' => 'wbEntitySelector'
] ),
new OOUI\ButtonInputWidget( [
'name' => 'request-qid',
'label' => $this->getPlainText( 'math-wikibase-special-form-button' ),
'type' => 'submit',
'flags' => [ 'primary', 'progressive' ],
'icon' => 'check',
] ),
[
'label' => $this->getPlainText( 'math-wikibase-special-form-header' ),
'align' => 'top'
]
);
$formLayout = new \OOUI\FormLayout( [
'method' => 'POST',
'items' => [ $actionField ]
] );
$this->getOutput()->addHTML( $formLayout );
}
/**
* Shows an error message for the user and writes information to $logger
* @param Exception $e can potentially be any exception.
*/
private function showError( Exception $e ) {
$this->getOutput()->setPageTitle(
$this->getPlainText( 'math-wikibase-special-error-header' )
);
if ( $e instanceof InvalidArgumentException ) {
$this->logger->warning( "An invalid ID was specified. Reason: " . $e->getMessage() );
$this->getOutput()->addHTML(
$this->msg( 'math-wikibase-special-error-invalid-argument' )->inContentLanguage()->parse()
);
} else {
$this->logger->error( "An unknown error occurred while fetching data from Wikibase.", [
'exception' => $e
] );
$this->getOutput()->addHTML(
$this->msg( 'math-wikibase-special-error-unknown' )->inContentLanguage()->parse()
);
}
}
/**
* Helper function to shorten i18n text processing
* @param string $key
* @return string the plain text in current content language
*/
private function getPlainText( $key ) {
return $this->msg( $key )->inContentLanguage()->plain();
}
/**
* @param MathWikibaseInfo $info
* @param string $qid
* @param OutputPage $output
*/
public static function buildPageRepresentation(
MathWikibaseInfo $info,
$qid,
OutputPage $output
) {
$output->setPageTitle( $info->getLabel() );
// if 'instance of' is specified, it can be found in the description before a colon
// FIXME: There are other reasons to have a colon in an Item's description, e.g.
// https://www.wikidata.org/wiki/Special:MathWikibase?qid=Q6203
if ( preg_match( '/(.*):\s*(.*)/', $info->getDescription(), $matches ) ) {
$output->setSubtitle( $matches[1] );
}
// add formula information
$header = wfMessage( 'math-wikibase-formula-information' )->inContentLanguage()->plain();
$output->addHTML( self::createHTMLHeader( $header ) );
if ( $info->getSymbol() ) {
$math = $info->getFormattedSymbol();
$formulaInfo = new Message( 'math-wikibase-formula-header-format' );
$formulaInfo->rawParams(
wfMessage( 'math-wikibase-formula' )->inContentLanguage(),
$math
);
$output->addHTML( Html::rawElement( "p", [], $formulaInfo->inContentLanguage()->parse() ) );
}
$labelName = wfMessage(
'math-wikibase-formula-header-format',
wfMessage( 'math-wikibase-formula-name' )->inContentLanguage(),
$info->getLabel()
)->inContentLanguage()->parse();
$output->addHTML( Html::rawElement( "p", [], $labelName ) );
if ( isset( $matches[2] ) ) {
$labelType = wfMessage(
'math-wikibase-formula-header-format',
wfMessage( 'math-wikibase-formula-type' )->inContentLanguage(),
$matches[1]
)->inContentLanguage()->parse();
$output->addHTML( Html::rawElement( "p", [], $labelType ) );
$description = $matches[2];
} else {
$description = $info->getDescription();
}
$labelDesc = wfMessage(
'math-wikibase-formula-header-format',
wfMessage( 'math-wikibase-formula-description' )->inContentLanguage(),
$description
)->inContentLanguage()->parse();
$output->addHTML( Html::rawElement( "p", [], $labelDesc ) );
// add parts of formula
if ( $info->hasParts() ) {
$elementsHeader = wfMessage( 'math-wikibase-formula-elements-header' )
->inContentLanguage()->plain();
$output->addHTML( self::createHTMLHeader( $elementsHeader ) );
$output->addHTML( $info->generateTableOfParts() );
}
// add link information
$wikibaseHeader = wfMessage(
'math-wikibase-formula-link-header',
$info->getDescription()
)->inContentLanguage()->plain();
$output->addHTML( self::createHTMLHeader( $wikibaseHeader ) );
$url = MathWikibaseConnector::buildURL( $qid );
$link = Html::linkButton( $url, [ "href" => $url ] );
$output->addHTML( Html::rawElement( "p", [], $link ) );
}
/**
* @param string $header Plain text
* @return string Raw HTML
*/
private static function createHTMLHeader( string $header ) : string {
return Html::rawElement(
'h2',
[],
Html::element( 'span', [ 'class' => 'mw-headline' ], $header )
);
}
/**
* Check whether Wikibase is available or not
* @return bool
*/
public static function isWikibaseAvailable() {
return class_exists( '\Wikibase\Client\WikibaseClient' );
}
}