-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHooks.php
166 lines (152 loc) · 4.81 KB
/
Hooks.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
<?php
/**
* @file
* @license GPL-3.0-or-later
*/
namespace MediaWiki\Extension\UnlinkedWikibase;
use Config;
use MediaWiki\Hook\InfoActionHook;
use MediaWiki\Hook\ParserFirstCallInitHook;
use MediaWiki\Html\Html;
use MediaWiki\MediaWikiServices;
use Parser;
use Wikimedia\ParamValidator\TypeDef\BooleanDef;
/**
* UnlinkedWikibase extension hooks.
*/
class Hooks implements ParserFirstCallInitHook, InfoActionHook {
private Config $config;
public function __construct( Config $mainConfig ) {
$this->config = $mainConfig;
}
/**
* @link https://www.mediawiki.org/wiki/Extension:Scribunto/Hooks/ScribuntoExternalLibraries
* @param string $engine
* @param string[] &$libs
*/
public static function onScribuntoExternalLibraries( $engine, array &$libs ) {
if ( $engine === 'lua' ) {
$libs['mw.ext.unlinkedwikibase'] = UnlinkedWikibaseLuaLibrary::class;
}
}
/**
* @inheritDoc
*/
public function onParserFirstCallInit( $parser ) {
$parser->setFunctionHook( 'unlinkedwikibase', [ $this, 'renderMainParserFunction' ] );
if ( $this->config->get( 'UnlinkedWikibaseStatementsParserFunc' ) ) {
$parser->setFunctionHook( 'statements', [ $this, 'renderStatements' ] );
}
return true;
}
/**
* @param Parser $parser
* @return mixed
*/
public function renderStatements( Parser $parser ) {
$params = $this->getParserFunctionArgs( func_get_args() );
if ( !isset( $params[0] ) ) {
return $this->getError( 'unlinkedwikibase-error-missing-property' );
}
$entityId = !empty( $params['from'] )
? $params['from']
: $parser->getOutput()->getPageProperty( 'unlinkedwikibase_id' );
if ( !$entityId ) {
return $this->getError( 'unlinkedwikibase-error-statements-entity-not-set' );
}
$wikibase = new Wikibase();
$propName = $params[0] ?? '';
$propId = $wikibase->getPropertyId( $parser, $propName );
if ( !$propId ) {
return $this->getError( 'unlinkedwikibase-error-property-name-not-found', [ $propName ] );
}
$entity = $wikibase->getEntity( $parser, $entityId );
if ( !isset( $entity['claims'][$propId] ) ) {
// No claim for this property.
return "<!-- No $propName ($propId) property found for $entityId -->";
}
$vals = [];
foreach ( $entity['claims'][$propId] as $claim ) {
$vals[] = $wikibase->formatClaimAsWikitext( $claim );
}
$out = $parser->getContentLanguage()->listToText( $vals );
return Html::rawElement( 'span', [ 'class' => 'ext-UnlinkedWikibase-statements' ], $out );
}
/**
* @param mixed[] $args
* @return string[]
*/
private function getParserFunctionArgs( array $args ) {
$params = [];
// Remove $parser from the args.
array_shift( $args );
foreach ( $args as $arg ) {
$pair = explode( '=', $arg, 2 );
if ( count( $pair ) == 2 ) {
$name = trim( $pair[0] );
$value = trim( $pair[1] );
if ( in_array( $value, BooleanDef::$TRUEVALS, true ) ) {
$value = true;
}
if ( in_array( $value, BooleanDef::$FALSEVALS, true ) ) {
$value = false;
}
if ( $value !== '' ) {
$params[$name] = $value;
}
} else {
$params[] = $arg;
}
}
return $params;
}
/**
* Render the output of the parser function.
* The input parameters are wikitext with templates expanded.
* The output should be wikitext too.
* @param Parser $parser The parser.
* @return string|mixed[] The wikitext with which to replace the parser function call.
*/
public function renderMainParserFunction( Parser $parser ) {
$params = $this->getParserFunctionArgs( func_get_args() );
if ( !isset( $params['id'] ) ) {
return $this->getError( 'unlinkedwikibase-error-missing-id' );
}
if ( !preg_match( '/^Q[0-9]+$/', $params['id'] ) ) {
return $this->getError( 'unlinkedwikibase-error-invalid-id', [ $params['id'] ] );
}
$parser->getOutput()->setPageProperty( 'unlinkedwikibase_id', $params['id'] );
return '';
}
/**
* Get an error message response.
* @param string $msg The i18n message name.
* @param string[] $params The parameters to use in the message.
* @return mixed[] The parser function response with the error message HTML.
*/
private function getError( string $msg, array $params = [] ) {
$label = wfMessage( 'unlinkedwikibase-error-label' )->text();
$labelHtml = Html::element( 'strong', [], $label );
$err = wfMessage( $msg, $params )->text();
$out = Html::rawElement( 'span', [ 'class' => 'error' ], "$labelHtml $err" );
return [ 0 => $out, 'isHTML' => true ];
}
/**
* Add the saved Wikibase ID to the page info table.
*
* {@inheritDoc}
*/
public function onInfoAction( $context, &$pageInfo ) {
$props = MediaWikiServices::getInstance()
->getPageProps()
->getProperties( $context->getTitle(), 'unlinkedwikibase_id' );
if ( !$props ) {
return true;
}
$pageInfo['header-basic'][] = [
wfMessage( 'unlinkedwikibase-infoaction-label' ),
array_shift( $props )
];
return true;
}
}