mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Math
synced 2024-11-23 15:16:56 +00:00
Add special page and API endpoint that show information from math Wikibase items
Add a special page and an API endpoint to fetch data from Wikibase items with a given qID. The special page summarizes information from Wikibase. The API endpoint allows to request the information directly. Both, the API endpoint and the special page, fetch the data from a new helper class for consistency. Bug: T208758 Bug: T229939 Change-Id: Idd22057a88312bf1a1cb5546d0a6edca5678d80d
This commit is contained in:
parent
0de63bdf6c
commit
4a7bc3ee31
|
@ -8,8 +8,7 @@ $cfg['directory_list'] = array_merge(
|
||||||
$cfg['directory_list'],
|
$cfg['directory_list'],
|
||||||
[
|
[
|
||||||
'../../extensions/VisualEditor',
|
'../../extensions/VisualEditor',
|
||||||
'../../extensions/Wikibase/repo',
|
'../../extensions/Wikibase'
|
||||||
'../../extensions/Wikibase/lib',
|
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -17,8 +16,7 @@ $cfg['exclude_analysis_directory_list'] = array_merge(
|
||||||
$cfg['exclude_analysis_directory_list'],
|
$cfg['exclude_analysis_directory_list'],
|
||||||
[
|
[
|
||||||
'../../extensions/VisualEditor',
|
'../../extensions/VisualEditor',
|
||||||
'../../extensions/Wikibase/repo',
|
'../../extensions/Wikibase'
|
||||||
'../../extensions/Wikibase/lib',
|
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -14,5 +14,6 @@ $specialPageAliases = [];
|
||||||
|
|
||||||
/** English (English) */
|
/** English (English) */
|
||||||
$specialPageAliases['en'] = [
|
$specialPageAliases['en'] = [
|
||||||
'MathShowImage' => [ 'MathShowImage' ]
|
'MathShowImage' => [ 'MathShowImage' ],
|
||||||
|
'MathWikibase' => [ 'MathWikibase' ]
|
||||||
];
|
];
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
"Tomasz Wegrzanowski",
|
"Tomasz Wegrzanowski",
|
||||||
"Brion Vibber",
|
"Brion Vibber",
|
||||||
"Moritz Schubotz",
|
"Moritz Schubotz",
|
||||||
"Derk-Jan Hartman"
|
"Derk-Jan Hartman",
|
||||||
|
"André Greiner-Petter"
|
||||||
],
|
],
|
||||||
"url": "https://www.mediawiki.org/wiki/Extension:Math",
|
"url": "https://www.mediawiki.org/wiki/Extension:Math",
|
||||||
"descriptionmsg": "math-desc",
|
"descriptionmsg": "math-desc",
|
||||||
|
@ -29,16 +30,26 @@
|
||||||
"MathInputCheckRestbase": "src/MathInputCheckRestbase.php",
|
"MathInputCheckRestbase": "src/MathInputCheckRestbase.php",
|
||||||
"SpecialMathShowImage": "src/SpecialMathShowImage.php",
|
"SpecialMathShowImage": "src/SpecialMathShowImage.php",
|
||||||
"SpecialMathStatus": "src/SpecialMathStatus.php",
|
"SpecialMathStatus": "src/SpecialMathStatus.php",
|
||||||
|
"SpecialMathWikibase": "src/SpecialMathWikibase.php",
|
||||||
"MathValidator": "src/MathValidator.php",
|
"MathValidator": "src/MathValidator.php",
|
||||||
"MathFormatter": "src/MathFormatter.php",
|
"MathFormatter": "src/MathFormatter.php",
|
||||||
"MathWikibaseHook": "src/MathWikibaseHook.php",
|
"MathWikibaseHook": "src/MathWikibaseHook.php",
|
||||||
"MathMLRdfBuilder": "src/MathMLRdfBuilder.php",
|
"MathMLRdfBuilder": "src/MathMLRdfBuilder.php",
|
||||||
"MathPng": "src/MathPng.php",
|
"MathPng": "src/MathPng.php",
|
||||||
"MathDataUpdater": "src/MathDataUpdater.php"
|
"MathDataUpdater": "src/MathDataUpdater.php",
|
||||||
|
"MathWikibaseConfig": "src/MathWikibaseConfig.php",
|
||||||
|
"MathWikibaseConnector": "src/MathWikibaseConnector.php",
|
||||||
|
"MathWikibaseInfo": "src/MathWikibaseInfo.php",
|
||||||
|
"ApiMathWikibaseExtracts": "src/ApiMathWikibaseExtracts.php"
|
||||||
},
|
},
|
||||||
"DefaultUserOptions": {
|
"DefaultUserOptions": {
|
||||||
"math": "mathml"
|
"math": "mathml"
|
||||||
},
|
},
|
||||||
|
"APIPropModules": {
|
||||||
|
"mathwbextracts": {
|
||||||
|
"class": "ApiMathWikibaseExtracts"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ExtensionMessagesFiles": {
|
"ExtensionMessagesFiles": {
|
||||||
"MathAlias": "Math.alias.php",
|
"MathAlias": "Math.alias.php",
|
||||||
"MathAliasNoTranslate": "Math.alias.noTranslate.php"
|
"MathAliasNoTranslate": "Math.alias.noTranslate.php"
|
||||||
|
@ -108,7 +119,11 @@
|
||||||
"source",
|
"source",
|
||||||
"mathml"
|
"mathml"
|
||||||
],
|
],
|
||||||
"MathEnableWikibaseDataType": true
|
"MathEnableWikibaseDataType": true,
|
||||||
|
"MathEnableFormulaLinks": false,
|
||||||
|
"MathWikibasePropertyIdHasPart": "P527",
|
||||||
|
"MathWikibasePropertyIdDefiningFormula": "P2534",
|
||||||
|
"MathWikibasePropertyIdQuantitySymbol": "P416"
|
||||||
},
|
},
|
||||||
"VisualEditorPluginModules": [
|
"VisualEditorPluginModules": [
|
||||||
"ext.math.visualEditor"
|
"ext.math.visualEditor"
|
||||||
|
@ -129,6 +144,12 @@
|
||||||
"ext.math.scripts": {
|
"ext.math.scripts": {
|
||||||
"scripts": "ext.math.js"
|
"scripts": "ext.math.js"
|
||||||
},
|
},
|
||||||
|
"ext.math.wikibase.scripts": {
|
||||||
|
"scripts": "ext.math.wikibase.js",
|
||||||
|
"dependencies": [
|
||||||
|
"jquery.wikibase.entityselector"
|
||||||
|
]
|
||||||
|
},
|
||||||
"ext.math.visualEditor": {
|
"ext.math.visualEditor": {
|
||||||
"scripts": [
|
"scripts": [
|
||||||
"ve-math/ve.dm.MWLatexNode.js",
|
"ve-math/ve.dm.MWLatexNode.js",
|
||||||
|
@ -246,7 +267,8 @@
|
||||||
},
|
},
|
||||||
"SpecialPages": {
|
"SpecialPages": {
|
||||||
"MathShowImage": "SpecialMathShowImage",
|
"MathShowImage": "SpecialMathShowImage",
|
||||||
"MathStatus": "SpecialMathStatus"
|
"MathStatus": "SpecialMathStatus",
|
||||||
|
"MathWikibase": "SpecialMathWikibase"
|
||||||
},
|
},
|
||||||
"TrackingCategories": [
|
"TrackingCategories": [
|
||||||
"math-tracking-category-error",
|
"math-tracking-category-error",
|
||||||
|
|
23
i18n/en.json
23
i18n/en.json
|
@ -95,7 +95,28 @@
|
||||||
"mw_math_source": "LaTeX source (for text browsers)",
|
"mw_math_source": "LaTeX source (for text browsers)",
|
||||||
"prefs-math": "Math",
|
"prefs-math": "Math",
|
||||||
"mathstatus": "Math status",
|
"mathstatus": "Math status",
|
||||||
|
"mathwikibase": "Math Formula Information",
|
||||||
"datatypes-type-math": "Mathematical expression",
|
"datatypes-type-math": "Mathematical expression",
|
||||||
"wikibase-listdatatypes-math-head": "Mathematical expression",
|
"wikibase-listdatatypes-math-head": "Mathematical expression",
|
||||||
"wikibase-listdatatypes-math-body": "Literal data field for mathematical expressions, formula, equations and such, expressed in a variant of LaTeX."
|
"wikibase-listdatatypes-math-body": "Literal data field for mathematical expressions, formula, equations and such, expressed in a variant of LaTeX.",
|
||||||
|
"math-wikibase-header": "Information of Mathematical Items",
|
||||||
|
"math-wikibase-formula": "Formula",
|
||||||
|
"math-wikibase-formula-name": "Name",
|
||||||
|
"math-wikibase-formula-type": "Type",
|
||||||
|
"math-wikibase-formula-header-format": "'''$1:''' $2",
|
||||||
|
"math-wikibase-formula-description": "Description",
|
||||||
|
"math-wikibase-formula-information": "Math Formula Information",
|
||||||
|
"math-wikibase-formula-link-header": "Data Source",
|
||||||
|
"math-wikibase-formula-elements-header": "Elements of the Forumla",
|
||||||
|
"math-wikibase-special-form-header": "Specify the name of the formula:",
|
||||||
|
"math-wikibase-special-form-placeholder": "Title of the formula",
|
||||||
|
"math-wikibase-special-form-button": "Request Information",
|
||||||
|
"math-wikibase-special-error-header": "Error",
|
||||||
|
"math-wikibase-special-error-invalid-argument": "Your specified Wikibase item ID does not exist.",
|
||||||
|
"math-wikibase-special-error-unknown": "An unknown error occured due fetching data from Wikibase.",
|
||||||
|
"math-wikibase-special-error-no-wikibase": "The Wikibase extension is required in order to use this special page.",
|
||||||
|
"apihelp-query+mathwbextracts-example-1": "Requests a summary of mathematical Wikibase items.",
|
||||||
|
"apihelp-query+mathwbextracts-summary": "Returns a summary of a mathematical Wikibase item in HTML.",
|
||||||
|
"apihelp-query+mathwbextracts-param-qid": "The QID of the Wikibase item that will be requested.",
|
||||||
|
"apihelp-query+mathwbextracts-param-uselang": "The language that should be requested for the Wikibase item. English is the default value."
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,28 @@
|
||||||
"mw_math_source": "In user preferences (math). All mw_math_* messages MUST be different, things will break otherwise!\n\nUsed as label for source radio button.\n\nSee also:\n* {{msg-mw|Mw math png}}\n* {{msg-mw|Mw math latexml}}",
|
"mw_math_source": "In user preferences (math). All mw_math_* messages MUST be different, things will break otherwise!\n\nUsed as label for source radio button.\n\nSee also:\n* {{msg-mw|Mw math png}}\n* {{msg-mw|Mw math latexml}}",
|
||||||
"prefs-math": "Used in user preferences as a section heading.\n{{Identical|Math}}",
|
"prefs-math": "Used in user preferences as a section heading.\n{{Identical|Math}}",
|
||||||
"mathstatus": "Title of a special page that displays information about the enabled math rendering modes.",
|
"mathstatus": "Title of a special page that displays information about the enabled math rendering modes.",
|
||||||
|
"mathwikibase": "Title of a special page that displays information about a mathematical Wikibase item.",
|
||||||
"datatypes-type-math": "The name of a data type.\n{{related|Datatypes-type}}\n{{Identical|Mathematical expression}}",
|
"datatypes-type-math": "The name of a data type.\n{{related|Datatypes-type}}\n{{Identical|Mathematical expression}}",
|
||||||
"wikibase-listdatatypes-math-head": "{{Wikibase-datatype-head|Mathematical expression|math}}\n{{Identical|Mathematical expression}}",
|
"wikibase-listdatatypes-math-head": "{{Wikibase-datatype-head|Mathematical expression|math}}\n{{Identical|Mathematical expression}}",
|
||||||
"wikibase-listdatatypes-math-body": "{{Wikibase-datatype-body|Mathematical expression}}"
|
"wikibase-listdatatypes-math-body": "{{Wikibase-datatype-body|Mathematical expression}}",
|
||||||
|
"apihelp-query+mathwbextracts-example-1": "{{doc-apihelp-example|query+mathwbextracts}}",
|
||||||
|
"apihelp-query+mathwbextracts-summary": "{{doc-apihelp-summary|query+mathwbextracts}}",
|
||||||
|
"apihelp-query+mathwbextracts-param-qid": "{{doc-apihelp-param|query+mathwbextracts|qid}}",
|
||||||
|
"apihelp-query+mathwbextracts-param-uselang": "{{doc-apihelp-param|query+mathwbextracts|uselang}}",
|
||||||
|
"math-wikibase-formula": "Label for the inline header for formulae",
|
||||||
|
"math-wikibase-formula-name": "Label for the name of the formula",
|
||||||
|
"math-wikibase-formula-type": "Label for the type of the formula",
|
||||||
|
"math-wikibase-formula-description": "Label for the description of the formula",
|
||||||
|
"math-wikibase-formula-information": "Header for information section of the formula",
|
||||||
|
"math-wikibase-formula-link-header": "Header for the hyperlink section to wikibase of the formula",
|
||||||
|
"math-wikibase-formula-elements-header": "Header for the elements section of the forumla",
|
||||||
|
"math-wikibase-formula-header-format": "The pattern to organize label $1 with information $2",
|
||||||
|
"math-wikibase-header": "wikibase Information of Mathematical Items",
|
||||||
|
"math-wikibase-special-form-header": "The header of the form to request a wikibase id from user.",
|
||||||
|
"math-wikibase-special-form-placeholder": "The placeholder of input field where a user can request a wikibase id.",
|
||||||
|
"math-wikibase-special-form-button": "The button label to submits the form to request a wikibase id.",
|
||||||
|
"math-wikibase-special-error-header": "The header of the error page. Will be shown when an error occured on the special page.",
|
||||||
|
"math-wikibase-special-error-invalid-argument": "The error text if the requested wikibase does not exist.",
|
||||||
|
"math-wikibase-special-error-unknown": "The error text when an unkown error occurred during fetching the information.\nFurther information about the error can be found in the logs.",
|
||||||
|
"math-wikibase-special-error-no-wikibase": "The error text that show up when the required Wikibase extension is missing."
|
||||||
}
|
}
|
||||||
|
|
17
modules/ext.math.wikibase.js
Normal file
17
modules/ext.math.wikibase.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
( function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var serverUrl = mw.config.get( 'wgServer' ),
|
||||||
|
scriptPath = mw.config.get( 'wgScriptPath' ),
|
||||||
|
repoApiUrl = serverUrl + scriptPath + '/api.php',
|
||||||
|
contLang = mw.config.get( 'wgContentLanguage' );
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-jquery/no-global-selector
|
||||||
|
$( '.mwe-math-wikibase-entityselector-input input' ).entityselector( {
|
||||||
|
url: repoApiUrl,
|
||||||
|
language: contLang,
|
||||||
|
type: 'item'
|
||||||
|
} ).on( 'entityselectorselected', function ( event, entityId ) {
|
||||||
|
this.value = entityId;
|
||||||
|
} );
|
||||||
|
}() );
|
154
src/ApiMathWikibaseExtracts.php
Normal file
154
src/ApiMathWikibaseExtracts.php
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API extension to fetch data from mathematical Wikibase items
|
||||||
|
*/
|
||||||
|
class ApiMathWikibaseExtracts extends ApiQueryBase {
|
||||||
|
/**
|
||||||
|
* @var string the prefix of the parameter names of this API
|
||||||
|
*/
|
||||||
|
const PREFIX = "math";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var MathWikibaseConnector
|
||||||
|
*/
|
||||||
|
private $wikibase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ApiQuery $query
|
||||||
|
* @param string $moduleName
|
||||||
|
*/
|
||||||
|
public function __construct( ApiQuery $query, $moduleName ) {
|
||||||
|
parent::__construct( $query, $moduleName, self::PREFIX );
|
||||||
|
$this->wikibase = new MathWikibaseConnector(
|
||||||
|
MathWikibaseConfig::getDefaultMathWikibaseConfig()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ApiUsageException
|
||||||
|
*/
|
||||||
|
public function execute() {
|
||||||
|
$result = $this->getResult();
|
||||||
|
$params = $this->extractRequestParams();
|
||||||
|
|
||||||
|
$qid = $params['qid'];
|
||||||
|
$lang = $params['uselang'] ?: 'en';
|
||||||
|
|
||||||
|
try {
|
||||||
|
$info = $this->wikibase->fetchWikibaseFromId( $qid, $lang );
|
||||||
|
$result->addValue(
|
||||||
|
[ 'query', 'mathwbextracts' ],
|
||||||
|
$qid,
|
||||||
|
$this->buildResponse( $qid, $lang, $info )
|
||||||
|
);
|
||||||
|
} catch ( MWException $e ) {
|
||||||
|
// impossible to fetch the data. Keep the answer empty
|
||||||
|
$result->addValue(
|
||||||
|
[ 'query', 'mathwbextracts' ],
|
||||||
|
$qid,
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $qid
|
||||||
|
* @param string $lang language code
|
||||||
|
* @param MathWikibaseInfo $info information from MathWikibaseConnector
|
||||||
|
* @return array response
|
||||||
|
*/
|
||||||
|
private function buildResponse( $qid, $lang, $info ) {
|
||||||
|
$specialPageTitle = Title::newFromText( "Special:MathWikibase" );
|
||||||
|
$url = $specialPageTitle->getLocalURL( [
|
||||||
|
'qid' => $qid
|
||||||
|
] );
|
||||||
|
|
||||||
|
try {
|
||||||
|
$langObj = Language::factory( $lang );
|
||||||
|
} catch ( MWException $e ) {
|
||||||
|
throw new InvalidArgumentException( "Invalid language code." );
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
"title" => $info->getLabel(),
|
||||||
|
"extract" => self::buildHTMLRepresentation( $info ),
|
||||||
|
"canonicalurl" => $url,
|
||||||
|
"fullurl" => $url,
|
||||||
|
"contentmodel" => "html",
|
||||||
|
"pagelanguage" => $langObj->getCode(),
|
||||||
|
"pagelanguagedir" => $langObj->getDir(),
|
||||||
|
"pagelanguagehtmlcode" => $langObj->getHtmlCode()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates an HTML string from the given data.
|
||||||
|
* @param MathWikibaseInfo $info an info object generated by fetchWikibaseFromId
|
||||||
|
* @return string an HTML representation of the given info object
|
||||||
|
*/
|
||||||
|
private function buildHTMLRepresentation( $info ) {
|
||||||
|
$output = Html::openElement(
|
||||||
|
"div",
|
||||||
|
[ "style" => "display: flex; flex-direction: row; align-items: flex-start; flow-wrap: wrap;" ]
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( $info->hasParts() ) {
|
||||||
|
$output .= Html::openElement( "div", [ "style" => "width: 70%;" ] );
|
||||||
|
} else {
|
||||||
|
$output .= Html::openElement( "div", [ "style" => "width: 100%;" ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
$output .= Html::element( "span", [ "style" => "font-weight: bold;" ], $info->getLabel() );
|
||||||
|
$output .= Html::element( "span", [], " (" . $info->getDescription() . ")" );
|
||||||
|
$output .= Html::closeElement( "div" );
|
||||||
|
|
||||||
|
if ( $info->hasParts() ) {
|
||||||
|
$output .= Html::openElement(
|
||||||
|
"div",
|
||||||
|
[ "style" => "width: 30%; display: flex; justify-content: center;" ]
|
||||||
|
);
|
||||||
|
$output .= $info->generateSmallTableOfParts();
|
||||||
|
$output .= Html::closeElement( "div" );
|
||||||
|
}
|
||||||
|
|
||||||
|
$output .= Html::closeElement( "div" );
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the parameters for this API endpoint
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getAllowedParams() {
|
||||||
|
return [
|
||||||
|
'qid' => [
|
||||||
|
ApiBase::PARAM_TYPE => 'string',
|
||||||
|
ApiBase::PARAM_REQUIRED => true
|
||||||
|
],
|
||||||
|
'uselang' => [
|
||||||
|
ApiBase::PARAM_TYPE => 'string',
|
||||||
|
ApiBase::PARAM_REQUIRED => false
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ApiBase::getExamplesMessages()
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getExamplesMessages() {
|
||||||
|
return [
|
||||||
|
'action=query&prop=mathwbextracts&mathqid=Q35875&mathuselang=en'
|
||||||
|
=> 'apihelp-query+mathwbextracts-example-1',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ApiBase::getHelpUrls()
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getHelpUrls() {
|
||||||
|
return 'https://www.mediawiki.org/wiki/Extension:Math#API';
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use MediaWiki\Logger\LoggerFactory;
|
use MediaWiki\Logger\LoggerFactory;
|
||||||
|
use MediaWiki\MediaWikiServices;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts LaTeX to MathML using the mathoid-server
|
* Converts LaTeX to MathML using the mathoid-server
|
||||||
|
@ -471,6 +472,8 @@ class MathMathML extends MathRenderer {
|
||||||
* @return string Html output that is embedded in the page
|
* @return string Html output that is embedded in the page
|
||||||
*/
|
*/
|
||||||
public function getHtmlOutput() {
|
public function getHtmlOutput() {
|
||||||
|
$config = MediaWikiServices::getInstance()->getMainConfig();
|
||||||
|
$enableLinks = $config->get( "MathEnableFormulaLinks" );
|
||||||
if ( $this->getMathStyle() == 'display' ) {
|
if ( $this->getMathStyle() == 'display' ) {
|
||||||
$element = 'div';
|
$element = 'div';
|
||||||
} else {
|
} else {
|
||||||
|
@ -480,10 +483,18 @@ class MathMathML extends MathRenderer {
|
||||||
if ( $this->getID() !== '' ) {
|
if ( $this->getID() !== '' ) {
|
||||||
$attribs['id'] = $this->getID();
|
$attribs['id'] = $this->getID();
|
||||||
}
|
}
|
||||||
|
$hyperlink = null;
|
||||||
if ( isset( $this->params['qid'] ) && preg_match( '/Q\d+/', $this->params['qid'] ) ) {
|
if ( isset( $this->params['qid'] ) && preg_match( '/Q\d+/', $this->params['qid'] ) ) {
|
||||||
$attribs['data-qid'] = $this->params['qid'];
|
$attribs['data-qid'] = $this->params['qid'];
|
||||||
|
// TODO: SpecialPage::getTitleFor uses the depcrated method Title::newFromTitleValue and
|
||||||
|
// declares a never thrown MWException. Once this SpecialPage is updated, update the next line.
|
||||||
|
$titleObj = Title::newFromLinkTarget( SpecialPage::getTitleValueFor( 'MathWikibase' ) );
|
||||||
|
$hyperlink = $titleObj->getLocalURL( [ 'qid' => $this->params['qid'] ] );
|
||||||
}
|
}
|
||||||
$output = Html::openElement( $element, $attribs );
|
$output = Html::openElement( $element, $attribs );
|
||||||
|
if ( $hyperlink && $enableLinks ) {
|
||||||
|
$output .= Html::openElement( 'a', [ 'href' => $hyperlink, 'style' => 'color:inherit;' ] );
|
||||||
|
}
|
||||||
// MathML has to be wrapped into a div or span in order to be able to hide it.
|
// MathML has to be wrapped into a div or span in order to be able to hide it.
|
||||||
// Remove displayStyle attributes set by the MathML converter
|
// Remove displayStyle attributes set by the MathML converter
|
||||||
// (Beginning from Mathoid 0.2.5 block is the default layout.)
|
// (Beginning from Mathoid 0.2.5 block is the default layout.)
|
||||||
|
@ -497,6 +508,9 @@ class MathMathML extends MathRenderer {
|
||||||
'class' => $this->getClassName(), 'style' => 'display: none;'
|
'class' => $this->getClassName(), 'style' => 'display: none;'
|
||||||
], $mml );
|
], $mml );
|
||||||
$output .= $this->getFallbackImage();
|
$output .= $this->getFallbackImage();
|
||||||
|
if ( $hyperlink && $enableLinks ) {
|
||||||
|
$output .= Html::closeElement( 'a' );
|
||||||
|
}
|
||||||
$output .= Html::closeElement( $element );
|
$output .= Html::closeElement( $element );
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
133
src/MathWikibaseConfig.php
Normal file
133
src/MathWikibaseConfig.php
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use MediaWiki\MediaWikiServices;
|
||||||
|
use Wikibase\DataModel\Entity\EntityIdParser;
|
||||||
|
use Wikibase\DataModel\Entity\PropertyId;
|
||||||
|
use Wikibase\Lib\Store\EntityRevisionLookup;
|
||||||
|
use Wikibase\Lib\Store\LanguageFallbackLabelDescriptionLookupFactory;
|
||||||
|
use Wikibase\Repo\WikibaseRepo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A config class for the MathWikibaseConnector to connect with Wikibase
|
||||||
|
* @see MathWikibaseConnector
|
||||||
|
*/
|
||||||
|
class MathWikibaseConfig {
|
||||||
|
/**
|
||||||
|
* @var EntityIdParser
|
||||||
|
*/
|
||||||
|
private $idParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var EntityRevisionLookup
|
||||||
|
*/
|
||||||
|
private $entityRevisionLookup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var LanguageFallbackLabelDescriptionLookupFactory
|
||||||
|
*/
|
||||||
|
private $labelLookupFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var PropertyId
|
||||||
|
*/
|
||||||
|
private $propertyIdHasPart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var PropertyId
|
||||||
|
*/
|
||||||
|
private $propertyIdQuantitySymbol;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var PropertyId
|
||||||
|
*/
|
||||||
|
private $propertyIdDefiningFormula;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var MathWikibaseConfig
|
||||||
|
*/
|
||||||
|
private static $defaultConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MathWikibaseConfig constructor.
|
||||||
|
* @param EntityIdParser $entityIdParser
|
||||||
|
* @param EntityRevisionLookup $entityRevisionLookup
|
||||||
|
* @param LanguageFallbackLabelDescriptionLookupFactory $labelDescriptionLookupFactory
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
EntityIdParser $entityIdParser,
|
||||||
|
EntityRevisionLookup $entityRevisionLookup,
|
||||||
|
LanguageFallbackLabelDescriptionLookupFactory $labelDescriptionLookupFactory
|
||||||
|
) {
|
||||||
|
$this->idParser = $entityIdParser;
|
||||||
|
$this->entityRevisionLookup = $entityRevisionLookup;
|
||||||
|
$this->labelLookupFactory = $labelDescriptionLookupFactory;
|
||||||
|
|
||||||
|
$config = MediaWikiServices::getInstance()->getMainConfig();
|
||||||
|
$this->propertyIdHasPart = $this->idParser->parse(
|
||||||
|
$config->get( "MathWikibasePropertyIdHasPart" )
|
||||||
|
);
|
||||||
|
$this->propertyIdDefiningFormula = $this->idParser->parse(
|
||||||
|
$config->get( "MathWikibasePropertyIdDefiningFormula" )
|
||||||
|
);
|
||||||
|
$this->propertyIdQuantitySymbol = $this->idParser->parse(
|
||||||
|
$config->get( "MathWikibasePropertyIdQuantitySymbol" )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return EntityIdParser
|
||||||
|
*/
|
||||||
|
public function getIdParser() : EntityIdParser {
|
||||||
|
return $this->idParser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return EntityRevisionLookup
|
||||||
|
*/
|
||||||
|
public function getEntityRevisionLookup() : EntityRevisionLookup {
|
||||||
|
return $this->entityRevisionLookup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return LanguageFallbackLabelDescriptionLookupFactory
|
||||||
|
*/
|
||||||
|
public function getLabelLookupFactory() : LanguageFallbackLabelDescriptionLookupFactory {
|
||||||
|
return $this->labelLookupFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return PropertyId
|
||||||
|
*/
|
||||||
|
public function getPropertyIdHasPart() : PropertyId {
|
||||||
|
return $this->propertyIdHasPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return PropertyId
|
||||||
|
*/
|
||||||
|
public function getPropertyIdQuantitySymbol() : PropertyId {
|
||||||
|
return $this->propertyIdQuantitySymbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return PropertyId
|
||||||
|
*/
|
||||||
|
public function getPropertyIdDefiningFormula() : PropertyId {
|
||||||
|
return $this->propertyIdDefiningFormula;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return MathWikibaseConfig default config
|
||||||
|
*/
|
||||||
|
public static function getDefaultMathWikibaseConfig() : MathWikibaseConfig {
|
||||||
|
if ( !self::$defaultConfig ) {
|
||||||
|
$wikibaseRepo = WikibaseRepo::getDefaultInstance();
|
||||||
|
self::$defaultConfig = new MathWikibaseConfig(
|
||||||
|
$wikibaseRepo->getEntityIdParser(),
|
||||||
|
$wikibaseRepo->getEntityRevisionLookup(),
|
||||||
|
$wikibaseRepo->getLanguageFallbackLabelDescriptionLookupFactory()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return self::$defaultConfig;
|
||||||
|
}
|
||||||
|
}
|
232
src/MathWikibaseConnector.php
Normal file
232
src/MathWikibaseConnector.php
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use DataValues\StringValue;
|
||||||
|
use Wikibase\Client\WikibaseClient;
|
||||||
|
use Wikibase\DataModel\Entity\EntityIdParsingException;
|
||||||
|
use Wikibase\DataModel\Entity\EntityIdValue;
|
||||||
|
use Wikibase\DataModel\Entity\Item;
|
||||||
|
use Wikibase\DataModel\Services\Lookup\LabelDescriptionLookup;
|
||||||
|
use Wikibase\DataModel\Snak\PropertyValueSnak;
|
||||||
|
use Wikibase\DataModel\Snak\Snak;
|
||||||
|
use Wikibase\DataModel\Statement\StatementList;
|
||||||
|
use Wikibase\Lib\Store\RevisionedUnresolvedRedirectException;
|
||||||
|
use Wikibase\Lib\Store\StorageException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class that connects with the local instance of wikibase to fetch
|
||||||
|
* information from single items. There is always only one instance of this class.
|
||||||
|
*
|
||||||
|
* @see WikibaseRepo::getDefaultInstance() the instance thats been used to fetch the data
|
||||||
|
* @see MathWikibaseConnector::getInstance() to get an instance of the class
|
||||||
|
*/
|
||||||
|
class MathWikibaseConnector {
|
||||||
|
/**
|
||||||
|
* @var MathWikibaseConfig
|
||||||
|
*/
|
||||||
|
private $config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MathWikibaseConnector constructor.
|
||||||
|
* @param MathWikibaseConfig $config
|
||||||
|
*/
|
||||||
|
public function __construct( MathWikibaseConfig $config ) {
|
||||||
|
$this->config = $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $qid
|
||||||
|
* @param string $langCode the language to fetch data
|
||||||
|
* (may fallback if requested language does not exist)
|
||||||
|
*
|
||||||
|
* @return MathWikibaseInfo the object may be empty if no information can be fetched.
|
||||||
|
* @throws InvalidArgumentException if the language code does not exist or the given
|
||||||
|
* id does not exist
|
||||||
|
*/
|
||||||
|
public function fetchWikibaseFromId( $qid, $langCode ) {
|
||||||
|
try {
|
||||||
|
$lang = Language::factory( $langCode );
|
||||||
|
} catch ( MWException $e ) {
|
||||||
|
throw new InvalidArgumentException( "Invalid language code specified." );
|
||||||
|
}
|
||||||
|
|
||||||
|
$langLookupFactory = $this->config->getLabelLookupFactory();
|
||||||
|
$langLookup = $langLookupFactory->newLabelDescriptionLookup( $lang );
|
||||||
|
|
||||||
|
$idParser = $this->config->getIdParser();
|
||||||
|
$entityRevisionLookup = $this->config->getEntityRevisionLookup();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$entityId = $idParser->parse( $qid ); // exception if the given ID is invalid
|
||||||
|
$entityRevision = $entityRevisionLookup->getEntityRevision( $entityId );
|
||||||
|
} catch ( EntityIdParsingException $e ) {
|
||||||
|
throw new InvalidArgumentException( "Invalid Wikibase ID." );
|
||||||
|
} catch ( RevisionedUnresolvedRedirectException $e ) {
|
||||||
|
throw new InvalidArgumentException( "Non-existing Wikibase ID." );
|
||||||
|
} catch ( StorageException $e ) {
|
||||||
|
throw new InvalidArgumentException( "Non-existing Wikibase ID." );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !$entityId || !$entityRevision ) {
|
||||||
|
throw new InvalidArgumentException( "Non-existing Wikibase ID." );
|
||||||
|
}
|
||||||
|
|
||||||
|
$entity = $entityRevision->getEntity();
|
||||||
|
$output = new MathWikibaseInfo( $entityId );
|
||||||
|
|
||||||
|
if ( $entity instanceof Item ) {
|
||||||
|
$this->fetchLabelDescription( $output, $langLookup );
|
||||||
|
$this->fetchStatements( $output, $entity, $langLookup );
|
||||||
|
return $output;
|
||||||
|
} else { // we only allow Wikibase items
|
||||||
|
throw new InvalidArgumentException( "The specified Wikibase ID does not represented an item." );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches only label and description from an entity.
|
||||||
|
* @param MathWikibaseInfo $output the entity id of the entity
|
||||||
|
* @param LabelDescriptionLookup $langLookup a lookup handler to fetch right languages
|
||||||
|
* @return MathWikibaseInfo filled up with label and description
|
||||||
|
*/
|
||||||
|
private function fetchLabelDescription(
|
||||||
|
MathWikibaseInfo $output,
|
||||||
|
LabelDescriptionLookup $langLookup ) {
|
||||||
|
$label = $langLookup->getLabel( $output->getId() );
|
||||||
|
$desc = $langLookup->getDescription( $output->getId() );
|
||||||
|
|
||||||
|
if ( $label ) {
|
||||||
|
$output->setLabel( $label->getText() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $desc ) {
|
||||||
|
$output->setDescription( $desc->getText() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches 'has part' statements from a given item element with a defined lookup object for
|
||||||
|
* the languages.
|
||||||
|
* @param MathWikibaseInfo $output the output element
|
||||||
|
* @param Item $item item to fetch statements from
|
||||||
|
* @param LabelDescriptionLookup $langLookup
|
||||||
|
* @return MathWikibaseInfo the updated $output object
|
||||||
|
*/
|
||||||
|
private function fetchStatements(
|
||||||
|
MathWikibaseInfo $output,
|
||||||
|
Item $item,
|
||||||
|
LabelDescriptionLookup $langLookup ) {
|
||||||
|
$statements = $item->getStatements();
|
||||||
|
|
||||||
|
$hasPartStatements = $statements->getByPropertyId( $this->config->getPropertyIdHasPart() );
|
||||||
|
$this->fetchHasPartSnaks( $output, $hasPartStatements, $langLookup );
|
||||||
|
|
||||||
|
$symbolStatement = $statements->getByPropertyId( $this->config->getPropertyIdDefiningFormula() );
|
||||||
|
if ( $symbolStatement->count() < 1 ) { // if it's not a formula, it might be a symbol
|
||||||
|
$symbolStatement = $statements->getByPropertyId( $this->config->getPropertyIdQuantitySymbol() );
|
||||||
|
}
|
||||||
|
$this->fetchSymbol( $output, $symbolStatement );
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the symbol or defining formula from a statement list and adds the symbol to the
|
||||||
|
* given info object
|
||||||
|
* @param MathWikibaseInfo $output
|
||||||
|
* @param StatementList $statements
|
||||||
|
* @return MathWikibaseInfo updated object
|
||||||
|
*/
|
||||||
|
private function fetchSymbol( MathWikibaseInfo $output, StatementList $statements ) {
|
||||||
|
foreach ( $statements as $statement ) {
|
||||||
|
$snak = $statement->getMainSnak();
|
||||||
|
if ( $snak instanceof PropertyValueSnak && $this->isQualifierDefinien( $snak ) ) {
|
||||||
|
$dataVal = $snak->getDataValue();
|
||||||
|
$symbol = new StringValue( $dataVal->getValue() );
|
||||||
|
$output->setSymbol( $symbol );
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches single snaks from 'has part' statements
|
||||||
|
*
|
||||||
|
* @param MathWikibaseInfo $output
|
||||||
|
* @param StatementList $statements the 'has part' statements
|
||||||
|
* @param LabelDescriptionLookup $langLookup
|
||||||
|
* @return MathWikibaseInfo
|
||||||
|
*@todo refactor this method once Wikibase has a more convenient way to handle snaks
|
||||||
|
*/
|
||||||
|
private function fetchHasPartSnaks(
|
||||||
|
MathWikibaseInfo $output,
|
||||||
|
StatementList $statements,
|
||||||
|
LabelDescriptionLookup $langLookup ) {
|
||||||
|
foreach ( $statements as $statement ) {
|
||||||
|
$snaks = $statement->getAllSnaks();
|
||||||
|
$innerInfo = null;
|
||||||
|
$symbol = null;
|
||||||
|
|
||||||
|
foreach ( $snaks as $snak ) {
|
||||||
|
if ( $snak instanceof PropertyValueSnak ) {
|
||||||
|
if ( $this->isQualifierDefinien( $snak ) ) {
|
||||||
|
$dataVal = $snak->getDataValue();
|
||||||
|
$symbol = new StringValue( $dataVal->getValue() );
|
||||||
|
} elseif ( $snak->getPropertyId()->equals( $this->config->getPropertyIdHasPart() ) ) {
|
||||||
|
$dataVal = $snak->getDataValue();
|
||||||
|
$entityIdValue = $dataVal->getValue();
|
||||||
|
if ( $entityIdValue instanceof EntityIdValue ) {
|
||||||
|
$innerEntityId = $entityIdValue->getEntityId();
|
||||||
|
$innerInfo = new MathWikibaseInfo( $innerEntityId );
|
||||||
|
$this->fetchLabelDescription( $innerInfo, $langLookup );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $innerInfo ) {
|
||||||
|
$innerInfo->setSymbol( $symbol );
|
||||||
|
$output->addHasPartElement( $innerInfo );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Snak $snak
|
||||||
|
* @return bool true if the given snak is either a defining formula or a quantity symbol
|
||||||
|
*/
|
||||||
|
private function isQualifierDefinien( Snak $snak ) {
|
||||||
|
return $snak->getPropertyId()->equals( $this->config->getPropertyIdQuantitySymbol() ) ||
|
||||||
|
$snak->getPropertyId()->equals( $this->config->getPropertyIdDefiningFormula() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo should be refactored once there is an easier way to get the URL
|
||||||
|
* @param string $qID
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function buildURL( $qID ) {
|
||||||
|
$baseurl = WikibaseClient::getDefaultInstance()
|
||||||
|
->getSettings()->getSetting( 'repoUrl' );
|
||||||
|
$articlePath = WikibaseClient::getDefaultInstance()
|
||||||
|
->getSettings()->getSetting( 'repoArticlePath' );
|
||||||
|
$namespaces = WikibaseClient::getDefaultInstance()
|
||||||
|
->getSettings()->getSetting( 'repoNamespaces' );
|
||||||
|
|
||||||
|
$url = $baseurl . $articlePath;
|
||||||
|
|
||||||
|
if ( $namespaces && $namespaces["item"] ) {
|
||||||
|
$articleId = $namespaces["item"] . ":" . $qID;
|
||||||
|
} else {
|
||||||
|
$articleId = $qID;
|
||||||
|
}
|
||||||
|
|
||||||
|
// repoArticlePath contains the placeholder $1 for the page title
|
||||||
|
// see: https://www.mediawiki.org/wiki/Manual:$wgArticlePath
|
||||||
|
return str_replace( '$1', $articleId, $url );
|
||||||
|
}
|
||||||
|
}
|
199
src/MathWikibaseInfo.php
Normal file
199
src/MathWikibaseInfo.php
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use DataValues\StringValue;
|
||||||
|
use MediaWiki\MediaWikiServices;
|
||||||
|
use Wikibase\DataModel\Entity\EntityId;
|
||||||
|
use Wikibase\Lib\Formatters\SnakFormatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class stores information about mathematical Wikibase items.
|
||||||
|
*/
|
||||||
|
class MathWikibaseInfo {
|
||||||
|
/**
|
||||||
|
* @var EntityId
|
||||||
|
*/
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string the label of the item
|
||||||
|
*/
|
||||||
|
private $label;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string description of the item
|
||||||
|
*/
|
||||||
|
private $description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var StringValue a symbol representing the item
|
||||||
|
*/
|
||||||
|
private $symbol;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var MathWikibaseInfo[]
|
||||||
|
*/
|
||||||
|
private $hasParts = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var MathFormatter
|
||||||
|
*/
|
||||||
|
private $mathFormatter;
|
||||||
|
|
||||||
|
public function __construct( EntityId $entityId ) {
|
||||||
|
$this->id = $entityId;
|
||||||
|
$this->mathFormatter = new MathFormatter( SnakFormatter::FORMAT_HTML );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $label
|
||||||
|
*/
|
||||||
|
public function setLabel( $label ) {
|
||||||
|
$this->label = $label;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $description
|
||||||
|
*/
|
||||||
|
public function setDescription( $description ) {
|
||||||
|
$this->description = $description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param StringValue $symbol
|
||||||
|
*/
|
||||||
|
public function setSymbol( $symbol ) {
|
||||||
|
$this->symbol = $symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param MathWikibaseInfo $info
|
||||||
|
*/
|
||||||
|
public function addHasPartElement( MathWikibaseInfo $info ) {
|
||||||
|
array_push( $this->hasParts, $info );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param MathWikibaseInfo[] $infos
|
||||||
|
*/
|
||||||
|
public function addHasPartElements( $infos ) {
|
||||||
|
array_push( $this->hasParts, ...$infos );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return EntityId id
|
||||||
|
*/
|
||||||
|
public function getId() {
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string label
|
||||||
|
*/
|
||||||
|
public function getLabel() {
|
||||||
|
return $this->label;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string description
|
||||||
|
*/
|
||||||
|
public function getDescription() {
|
||||||
|
return $this->description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return StringValue symbol
|
||||||
|
*/
|
||||||
|
public function getSymbol() {
|
||||||
|
return $this->symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string|null html formatted version of the symbol
|
||||||
|
*/
|
||||||
|
public function getFormattedSymbol() {
|
||||||
|
if ( $this->symbol ) {
|
||||||
|
return $this->mathFormatter->format( $this->getSymbol() );
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return MathWikibaseInfo[] hasparts
|
||||||
|
*/
|
||||||
|
public function getParts() {
|
||||||
|
return $this->hasParts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this info object has elements?
|
||||||
|
* @return bool true if there are elements otherwise false
|
||||||
|
*/
|
||||||
|
public function hasParts() {
|
||||||
|
if ( !$this->hasParts ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return $this->hasParts !== [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates an HTML table representation of the has-parts elements
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function generateTableOfParts() {
|
||||||
|
$lang = MediaWikiServices::getInstance()->getContentLanguage();
|
||||||
|
$labelAlign = $lang->isRTL() ? 'left' : 'right';
|
||||||
|
$labelAlignOpposite = !$lang->isRTL() ? 'left' : 'right';
|
||||||
|
|
||||||
|
$output = HTML::openElement( "table", [ "style" => "padding: 5px" ] );
|
||||||
|
$output .= HTML::openElement( "tbody" );
|
||||||
|
|
||||||
|
foreach ( $this->hasParts as $part ) {
|
||||||
|
$output .= HTML::openElement( "tr" );
|
||||||
|
$output .= HTML::element(
|
||||||
|
"td",
|
||||||
|
[ "style" => "font-weight: bold; text-align:$labelAlign;" ],
|
||||||
|
$part->getLabel()
|
||||||
|
);
|
||||||
|
$output .= HTML::rawElement(
|
||||||
|
"td",
|
||||||
|
[ "style" => "text-align:center; padding: 2px; padding-left: 10px; padding-right: 10px;" ],
|
||||||
|
$part->getFormattedSymbol()
|
||||||
|
);
|
||||||
|
$output .= HTML::element(
|
||||||
|
"td",
|
||||||
|
[ "style" => "font-style: italic; text-align:$labelAlignOpposite;" ],
|
||||||
|
$part->getDescription()
|
||||||
|
);
|
||||||
|
$output .= HTML::closeElement( "tr" );
|
||||||
|
}
|
||||||
|
|
||||||
|
$output .= HTML::closeElement( "tbody" );
|
||||||
|
$output .= HTML::closeElement( "table" );
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a minimalized HTML representation of the has-parts elements.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function generateSmallTableOfParts() {
|
||||||
|
$output = HTML::openElement( "table" );
|
||||||
|
$output .= HTML::openElement( "tbody" );
|
||||||
|
|
||||||
|
foreach ( $this->hasParts as $part ) {
|
||||||
|
$output .= HTML::openElement( "tr" );
|
||||||
|
$output .= HTML::rawElement(
|
||||||
|
"td",
|
||||||
|
[ "style" => "text-align:right;" ],
|
||||||
|
$part->getFormattedSymbol()
|
||||||
|
);
|
||||||
|
$output .= HTML::element( "td", [ "style" => "text-align:left;" ], $part->getLabel() );
|
||||||
|
$output .= HTML::closeElement( "tr" );
|
||||||
|
}
|
||||||
|
|
||||||
|
$output .= HTML::closeElement( "tbody" );
|
||||||
|
$output .= HTML::closeElement( "table" );
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
}
|
258
src/SpecialMathWikibase.php
Normal file
258
src/SpecialMathWikibase.php
Normal file
|
@ -0,0 +1,258 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
use MediaWiki\Logger\LoggerFactory;
|
||||||
|
|
||||||
|
class SpecialMathWikibase extends SpecialPage {
|
||||||
|
/**
|
||||||
|
* The parameter for this special page
|
||||||
|
*/
|
||||||
|
const PARAMETER = "qid";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var MathWikibaseConnector Wikibase connection
|
||||||
|
*/
|
||||||
|
private $wikibase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Psr\Log\LoggerInterface
|
||||||
|
*/
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SpecialMathWikibase constructor.
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct(
|
||||||
|
'MathWikibase',
|
||||||
|
'', // no restriciton
|
||||||
|
true // show on Special:SpecialPages
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->logger = LoggerFactory::getInstance( 'Math' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function execute( $par ) {
|
||||||
|
global $wgContLanguageCode;
|
||||||
|
|
||||||
|
if ( !$this->isWikibaseAvailable() ) {
|
||||||
|
$out = $this->getOutput();
|
||||||
|
|
||||||
|
$out->setPageTitle(
|
||||||
|
$this->getPlainText( 'math-wikibase-special-error-header' )
|
||||||
|
);
|
||||||
|
$out->addHTML(
|
||||||
|
wfMessage( 'math-wikibase-special-error-no-wikibase' )->inContentLanguage()
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !$this->wikibase ) {
|
||||||
|
$this->wikibase = new MathWikibaseConnector(
|
||||||
|
MathWikibaseConfig::getDefaultMathWikibaseConfig()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$output = $this->getOutput();
|
||||||
|
$output->enableOOUI();
|
||||||
|
|
||||||
|
$this->setHeaders();
|
||||||
|
$output->addModules( [ 'ext.math.wikibase.scripts' ] );
|
||||||
|
|
||||||
|
$output->setPageTitle(
|
||||||
|
$this->getPlainText( 'math-wikibase-header' )
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get request
|
||||||
|
$requestId = $request->getText( self::PARAMETER );
|
||||||
|
|
||||||
|
// 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, $wgContLanguageCode );
|
||||||
|
$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 \OOUI\TextInputWidget( [
|
||||||
|
'name' => self::PARAMETER,
|
||||||
|
'placeholder' => $this->getPlainText( 'math-wikibase-special-form-placeholder' ),
|
||||||
|
'required' => true,
|
||||||
|
'autocomplete' => false,
|
||||||
|
'classes' => [ 'mwe-math-wikibase-entityselector-input' ]
|
||||||
|
] ),
|
||||||
|
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(
|
||||||
|
wfMessage( 'math-wikibase-special-error-invalid-argument' )->inContentLanguage()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->logger->error( "An unknown error occured due fetching data from Wikibase.", [
|
||||||
|
'exception' => $e
|
||||||
|
] );
|
||||||
|
$this->getOutput()->addHTML(
|
||||||
|
wfMessage( 'math-wikibase-special-error-unknown' )->inContentLanguage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to shorten i18n text processing
|
||||||
|
* @param string $key
|
||||||
|
* @return string the plain text in current content language
|
||||||
|
*/
|
||||||
|
private function getPlainText( $key ) {
|
||||||
|
return wfMessage( $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
|
||||||
|
preg_match( '/(.*):\s*(.*)/', $info->getDescription(), $matches );
|
||||||
|
|
||||||
|
if ( count( $matches ) > 1 ) {
|
||||||
|
$output->setSubtitle( $matches[1] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// add formula information
|
||||||
|
$header = wfMessage( 'math-wikibase-formula-information' )->inContentLanguage();
|
||||||
|
$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() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$labelName = wfMessage(
|
||||||
|
'math-wikibase-formula-header-format',
|
||||||
|
wfMessage( 'math-wikibase-formula-name' )->inContentLanguage(),
|
||||||
|
$info->getLabel()
|
||||||
|
)->inContentLanguage();
|
||||||
|
$output->addHTML( HTML::rawElement( "p", [], $labelName ) );
|
||||||
|
|
||||||
|
if ( count( $matches ) > 2 ) {
|
||||||
|
$labelType = wfMessage(
|
||||||
|
'math-wikibase-formula-header-format',
|
||||||
|
wfMessage( 'math-wikibase-formula-type' )->inContentLanguage(),
|
||||||
|
$matches[1]
|
||||||
|
)->inContentLanguage();
|
||||||
|
|
||||||
|
$labelDesc = wfMessage(
|
||||||
|
'math-wikibase-formula-header-format',
|
||||||
|
wfMessage( 'math-wikibase-formula-description' )->inContentLanguage(),
|
||||||
|
$matches[2]
|
||||||
|
)->inContentLanguage();
|
||||||
|
|
||||||
|
$output->addHTML( HTML::rawElement( "p", [], $labelType ) );
|
||||||
|
$output->addHTML( HTML::rawElement( "p", [], $labelDesc ) );
|
||||||
|
} else {
|
||||||
|
$labelDesc = wfMessage(
|
||||||
|
'math-wikibase-formula-header-format',
|
||||||
|
wfMessage( 'math-wikibase-formula-description' )->inContentLanguage(),
|
||||||
|
$info->getDescription()
|
||||||
|
)->inContentLanguage();
|
||||||
|
$output->addHTML( HTML::rawElement( "p", [], $labelDesc ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// add parts of formula
|
||||||
|
if ( $info->hasParts() ) {
|
||||||
|
$elementsHeader = wfMessage( 'math-wikibase-formula-elements-header' )
|
||||||
|
->inContentLanguage()->escaped();
|
||||||
|
$output->addHTML( self::createHTMLHeader( $elementsHeader ) );
|
||||||
|
$output->addHTML( $info->generateTableOfParts() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// add link information
|
||||||
|
$wikibaseHeader = wfMessage(
|
||||||
|
'math-wikibase-formula-link-header',
|
||||||
|
$info->getDescription()
|
||||||
|
)->inContentLanguage();
|
||||||
|
|
||||||
|
$output->addHTML( self::createHTMLHeader( $wikibaseHeader ) );
|
||||||
|
|
||||||
|
$url = MathWikibaseConnector::buildURL( $qid );
|
||||||
|
$link = HTML::linkButton( $url, [ "href" => $url ] );
|
||||||
|
$output->addHTML( HTML::rawElement( "p", [], $link ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a header as HTML
|
||||||
|
* @param $header
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function createHTMLHeader( $header ) {
|
||||||
|
$headerOut = HTML::openElement( "h2" );
|
||||||
|
$headerOut .= HTML::rawElement( "span", [ "class" => "mw-headline" ], $header );
|
||||||
|
$headerOut .= HTML::closeElement( "h2" );
|
||||||
|
return $headerOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether Wikibase is available or not
|
||||||
|
* @return true|false
|
||||||
|
*/
|
||||||
|
public static function isWikibaseAvailable() {
|
||||||
|
return class_exists( '\Wikibase\Client\WikibaseClient' ) &&
|
||||||
|
class_exists( '\Wikibase\Repo\WikibaseRepo' );
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue