Math/src/MathWikibaseHook.php

78 lines
2.2 KiB
PHP
Raw Permalink Normal View History

<?php
use ValueFormatters\FormatterOptions;
use ValueParsers\StringParser;
use Wikibase\Rdf\DedupeBag;
use Wikibase\Rdf\EntityMentionListener;
use Wikibase\Rdf\RdfVocabulary;
use Wikibase\Repo\Parsers\WikibaseStringValueNormalizer;
use Wikibase\Repo\WikibaseRepo;
use Wikimedia\Purtle\RdfWriter;
class MathWikibaseHook {
/**
* Add Datatype "Math" to the Wikibase Repository
Don't expect objects by reference in hook handlers The motivation for this patch is to make the code less complex, better readable, and less brittle. Example: public function onExampleHook( Parser &$parser, array &$result ) { /* This is the hook handler */ } In this example the $result array is meant to be manipulated by the hook handler. Changes should become visible to the caller. Since PHP passes arrays by value, the & is needed to make this possible. But the & is misplaced in pretty much all cases where the parameter is an object. The only reason we still see these & in many hook handlers is historical: PHP 4 passed objects by value, which potentially caused expensive cloning. This was prevented with the &. Since PHP 5 objects are passed by reference. However, this did not made the & entirely meaningless. Keeping the & means callees are allowed to replace passed objects with new ones. The & makes it look like a function might intentionally replace a passed object, which is unintended and actually scary in cases like the Parser. Luckily all Hooks::run I have seen so far ignore unintended out-values. So even if a hook handler tries to do something bad like replacing the Parser with a different one, this would not have an effect. Removing the & does not remove the possibility to manipulate the object. Changes done to public properties are still visible to the caller. Unfortunately these & cannot be removed from the callers as long as there is a single callee expecting a reference. This patch reduces the number of such problematic callees. Change-Id: I21d53c989ea487607dc69e6b3365c023ef6729f5
2018-05-15 15:50:08 +00:00
* @param array[] &$dataTypeDefinitions
*/
public static function onWikibaseRepoDataTypes( array &$dataTypeDefinitions ) {
global $wgMathEnableWikibaseDataType;
if ( !$wgMathEnableWikibaseDataType ) {
return;
}
$dataTypeDefinitions['PT:math'] = [
'value-type' => 'string',
'validator-factory-callback' => function () {
// load validator builders
$factory = WikibaseRepo::getDefaultValidatorBuilders();
// initialize an array with string validators
// returns an array of validators
// that add basic string validation such as preventing empty strings
$validators = $factory->buildStringValidators();
$validators[] = new MathValidator();
return $validators;
},
'parser-factory-callback' => function ( ParserOptions $options ) {
$repo = WikibaseRepo::getDefaultInstance();
$normalizer = new WikibaseStringValueNormalizer( $repo->getStringNormalizer() );
return new StringParser( $normalizer );
},
'formatter-factory-callback' => function ( $format, FormatterOptions $options ) {
return new MathFormatter( $format );
},
'rdf-builder-factory-callback' => function (
$mode,
RdfVocabulary $vocab,
RdfWriter $writer,
EntityMentionListener $tracker,
DedupeBag $dedupe
) {
return new MathMLRdfBuilder();
},
];
}
/**
* Add Datatype "Math" to the Wikibase Client
Don't expect objects by reference in hook handlers The motivation for this patch is to make the code less complex, better readable, and less brittle. Example: public function onExampleHook( Parser &$parser, array &$result ) { /* This is the hook handler */ } In this example the $result array is meant to be manipulated by the hook handler. Changes should become visible to the caller. Since PHP passes arrays by value, the & is needed to make this possible. But the & is misplaced in pretty much all cases where the parameter is an object. The only reason we still see these & in many hook handlers is historical: PHP 4 passed objects by value, which potentially caused expensive cloning. This was prevented with the &. Since PHP 5 objects are passed by reference. However, this did not made the & entirely meaningless. Keeping the & means callees are allowed to replace passed objects with new ones. The & makes it look like a function might intentionally replace a passed object, which is unintended and actually scary in cases like the Parser. Luckily all Hooks::run I have seen so far ignore unintended out-values. So even if a hook handler tries to do something bad like replacing the Parser with a different one, this would not have an effect. Removing the & does not remove the possibility to manipulate the object. Changes done to public properties are still visible to the caller. Unfortunately these & cannot be removed from the callers as long as there is a single callee expecting a reference. This patch reduces the number of such problematic callees. Change-Id: I21d53c989ea487607dc69e6b3365c023ef6729f5
2018-05-15 15:50:08 +00:00
* @param array[] &$dataTypeDefinitions
*/
public static function onWikibaseClientDataTypes( array &$dataTypeDefinitions ) {
global $wgMathEnableWikibaseDataType;
if ( !$wgMathEnableWikibaseDataType ) {
return;
}
$dataTypeDefinitions['PT:math'] = [
'value-type' => 'string',
'formatter-factory-callback' => function ( $format, FormatterOptions $options ) {
return new MathFormatter( $format );
},
];
}
}