Daniel Kinzler has uploaded a new change for review.
https://gerrit.wikimedia.org/r/97510
Change subject: (bug #57014) Introducing FormatSnakValue API module
......................................................................
(bug #57014) Introducing FormatSnakValue API module
Change-Id: Ide20888b8943b87c9900862a125decf1f01dde53
---
M repo/Wikibase.classes.php
M repo/Wikibase.php
A repo/includes/api/FormatSnakValue.php
A repo/tests/phpunit/includes/api/FormatSnakValueTest.php
4 files changed, 354 insertions(+), 0 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase
refs/changes/10/97510/1
diff --git a/repo/Wikibase.classes.php b/repo/Wikibase.classes.php
index 60c792d..6bf7a7d 100644
--- a/repo/Wikibase.classes.php
+++ b/repo/Wikibase.classes.php
@@ -111,6 +111,7 @@
'Wikibase\Api\ModifyClaim' => 'includes/api/ModifyClaim.php',
'Wikibase\Api\ClaimModificationHelper' =>
'includes/api/ClaimModificationHelper.php',
'Wikibase\Api\ResultBuilder' =>
'includes/api/ResultBuilder.php',
+ 'Wikibase\Api\FormatSnakValue' =>
'includes/api/FormatSnakValue.php',
// includes/serializers
'Wikibase\Serializers\EntityRevisionSerializer' =>
'includes/serializers/EntityRevisionSerializer.php',
diff --git a/repo/Wikibase.php b/repo/Wikibase.php
index a2298ff..5d78a4e 100644
--- a/repo/Wikibase.php
+++ b/repo/Wikibase.php
@@ -123,6 +123,7 @@
$wgAPIModules['wbremovequalifiers'] =
'Wikibase\Api\RemoveQualifiers';
$wgAPIModules['wbsetqualifier'] =
'Wikibase\Api\SetQualifier';
$wgAPIModules['wbmergeitems'] =
'Wikibase\Api\MergeItems';
+ $wgAPIModules['wbformatvalue'] =
'Wikibase\Api\FormatSnakValue';
// Special page registration
$wgSpecialPages['NewItem']
= 'Wikibase\Repo\Specials\SpecialNewItem';
diff --git a/repo/includes/api/FormatSnakValue.php
b/repo/includes/api/FormatSnakValue.php
new file mode 100644
index 0000000..ec49faf
--- /dev/null
+++ b/repo/includes/api/FormatSnakValue.php
@@ -0,0 +1,247 @@
+<?php
+
+namespace Wikibase\Api;
+
+use ApiBase;
+use DataValues\DataValue;
+use DataValues\DataValueFactory;
+use DataValues\IllegalValueException;
+use LogicException;
+use ValueFormatters\FormatterOptions;
+use ValueFormatters\ValueFormatter;
+use Wikibase\Lib\OutputFormatValueFormatterFactory;
+use Wikibase\Lib\SnakFormatter;
+use Wikibase\Lib\TypedValueFormatter;
+use Wikibase\Repo\WikibaseRepo;
+
+/**
+ * API module for using value formatters.
+ *
+ * @since 0.5
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ */
+class FormatSnakValue extends ApiWikibase {
+
+ /**
+ * @var null|OutputFormatValueFormatterFactory
+ */
+ protected $formatterFactory = null;
+
+ /**
+ * @var null|DataValueFactory
+ */
+ protected $valueFactory = null;
+
+ /**
+ * @return OutputFormatValueFormatterFactory
+ */
+ protected function getFormatterFactory() {
+ if ( $this->formatterFactory === null ) {
+
+ $this->formatterFactory =
WikibaseRepo::getDefaultInstance()->getValueFormatterFactory();
+ }
+
+ return $this->formatterFactory;
+ }
+
+ /**
+ * @return DataValueFactory
+ */
+ protected function getValueFactory() {
+ if ( $this->valueFactory === null ) {
+ $this->valueFactory =
WikibaseRepo::getDefaultInstance()->getDataValueFactory();
+ }
+
+ return $this->valueFactory;
+ }
+
+ /**
+ * @see ApiBase::execute
+ *
+ * @since 0.1
+ */
+ public function execute() {
+ $params = $this->extractRequestParams();
+
+ $value = $this->decodeDataValue( $params['datavalue'] );
+ $dataTypeId = $this->getDataTypeId( $params );
+
+ $formatter = $this->getFormatter( $value );
+
+ if ( $formatter instanceof TypedValueFormatter ) {
+ // use data type id, if we can
+ $formattedValue = $formatter->formatValue( $value,
$dataTypeId );
+ } else {
+ // rely on value type
+ $formattedValue = $formatter->format( $value );
+ }
+
+ $this->getResult()->addValue(
+ null,
+ 'result',
+ $formattedValue
+ );
+ }
+
+ /**
+ * @throws \LogicException
+ * @return ValueFormatter
+ */
+ private function getFormatter() {
+ $params = $this->extractRequestParams();
+
+ $options = $this->getOptionsObject( $params['options'] );
+ $formatter = $this->getFormatterFactory()->getValueFormatter(
$params['generate'], $options );
+
+ // Paranoid check, should never fail since we only accept well
known values for the 'generate' parameter
+ if ( $formatter === null ) {
+ throw new LogicException( 'Could not obtain a
ValueFormatter instance for ' . $params['generate'] );
+ }
+
+ return $formatter;
+ }
+
+ /**
+ * @since 0.1
+ *
+ * @param string $json A JSON-encoded DataValue
+ *
+ * @return DataValue
+ */
+ protected function decodeDataValue( $json ) {
+ $data = \FormatJson::decode( $json, true );
+
+ if ( !is_array( $data ) ) {
+ $this->dieUsage( 'Failed to decode datavalue',
'baddatavalue' );
+ }
+
+ try {
+ $value = $this->getValueFactory()->newFromArray( $data
);
+ return $value;
+ } catch ( IllegalValueException $ex ) {
+ $this->dieUsage( $ex->getMessage(), 'baddatavalue' );
+ }
+ }
+
+ /**
+ * @since 0.1
+ *
+ * @param string $optionsParam
+ *
+ * @return FormatterOptions
+ */
+ protected function getOptionsObject( $optionsParam ) {
+ $formatterOptions = new FormatterOptions();
+ $formatterOptions->setOption( ValueFormatter::OPT_LANG,
$this->getLanguage()->getCode() );
+
+ $options = \FormatJson::decode( $optionsParam, true );
+
+ if ( is_array( $options ) ) {
+ foreach ( $options as $name => $value ) {
+ $formatterOptions->setOption( $name, $value );
+ }
+ }
+
+ return $formatterOptions;
+ }
+
+ /**
+ * Returns the data type ID specified by the parameters.
+ *
+ * @param array $params
+ * @return string|null
+ */
+ protected function getDataTypeId( array $params ) {
+ //TODO: could be looked up based on a property ID
+ return $params['datatype'];
+ }
+
+ /**
+ * @see ApiBase::getAllowedParams
+ *
+ * @since 0.1
+ *
+ * @return array
+ */
+ public function getAllowedParams() {
+ return array(
+ 'generate' => array(
+ ApiBase::PARAM_TYPE => array(
+ SnakFormatter::FORMAT_PLAIN,
+ SnakFormatter::FORMAT_WIKI,
+ SnakFormatter::FORMAT_HTML,
+ SnakFormatter::FORMAT_HTML_WIDGET,
+ ),
+ ApiBase::PARAM_DFLT =>
SnakFormatter::FORMAT_WIKI,
+ ApiBase::PARAM_REQUIRED => false,
+ ),
+ 'datavalue' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ 'datatype' => array(
+ ApiBase::PARAM_TYPE =>
WikibaseRepo::getDefaultInstance()->getDataTypeFactory()->getTypeIds(),
+ ApiBase::PARAM_REQUIRED => false,
+ ),
+ 'options' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => false,
+ ),
+ );
+ }
+
+ /**
+ * @see ApiBase::getParamDescription
+ *
+ * @since 0.1
+ *
+ * @return array
+ */
+ public function getParamDescription() {
+ return array(
+ 'generate' => 'The desired output format to generate.',
+ 'datatype' => 'The value\'s data type. This is distinct
from the value\'s type',
+ 'datavalue' => 'The data to format. This has to be the
JSON serialization of a DataValue object.',
+ 'options' => 'The options the formatter should use.
Provided as a JSON object.',
+ );
+ }
+
+ /**
+ * @see ApiBase::getDescription
+ *
+ * @since 0.1
+ *
+ * @return string
+ */
+ public function getDescription() {
+ return array(
+ 'API module for formatting DataValues.'
+ );
+ }
+
+ /**
+ * @see ApiBase::getExamples
+ *
+ * @since 0.1
+ *
+ * @return array
+ */
+ protected function getExamples() {
+ return array(
+ // 'ex' => 'desc' // TODO
+ );
+ }
+
+ /**
+ * @see ApiBase::getHelpUrls
+ *
+ * @since 0.1
+ *
+ * @return string
+ */
+ public function getHelpUrls() {
+ return ''; // TODO
+ }
+}
diff --git a/repo/tests/phpunit/includes/api/FormatSnakValueTest.php
b/repo/tests/phpunit/includes/api/FormatSnakValueTest.php
new file mode 100644
index 0000000..8b54f4a
--- /dev/null
+++ b/repo/tests/phpunit/includes/api/FormatSnakValueTest.php
@@ -0,0 +1,105 @@
+<?php
+
+namespace Wikibase\Test\Api;
+
+use DataValues\DataValue;
+use DataValues\StringValue;
+use DataValues\TimeValue;
+use ValueFormatters\TimeFormatter;
+use Wikibase\Lib\SnakFormatter;
+
+/**
+ * @covers Wikibase\Api\FormatSnakValue
+ *
+ * @since 0.1
+ *
+ * @group Wikibase
+ * @group WikibaseApi
+ *
+ * @group medium
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ */
+class FormatSnakValueTest extends \ApiTestCase {
+
+ public function provideApiRequest() {
+ $november11 = new TimeValue( '+2013-11-11T01:02:03Z',
+ 1 * 60 * 60, 0, 0,
+ TimeValue::PRECISION_DAY,
+ TimeFormatter::CALENDAR_GREGORIAN );
+
+ return array(
+ array( new StringValue( 'test' ),
+ null,
+ null,
+ null,
+ '/^test$/' ),
+
+ array( $november11,
+ null,
+ null,
+ array( TimeFormatter::OPT_LANG => 'en' ),
+ '/^11 November 2013$/' ),
+
+ /* // TimeFormatter is currently bypassed; This test
can only work once we start using it again.
+ array( $november11,
+ null,
+ null,
+ array(
+ TimeFormatter::OPT_LANG => 'en',
+ TimeFormatter::OPT_CALENDARNAMES =>
array( 'http://acme.org' => 'ACME' ),
+ TimeFormatter::OPT_TIME_ISO_FORMATTER
=> null
+ ),
+ '/^\+2013-11-11T01:02:03Z (ACME)$/' ),
+ */
+
+ array( new StringValue( 'http://acme.test' ),
+ 'string',
+ SnakFormatter::FORMAT_PLAIN,
+ null,
+ '@^http://acme\.test$@' ),
+
+ array( new StringValue( 'http://acme.test' ),
+ 'string',
+ SnakFormatter::FORMAT_WIKI,
+ null,
+ '@^http://acme\.test$@' ),
+
+ array( new StringValue( 'http://acme.test' ),
+ 'url',
+ SnakFormatter::FORMAT_PLAIN,
+ null,
+ '@^http://acme\.test$@' ),
+
+ array( new StringValue( 'http://acme.test' ),
+ 'url',
+ SnakFormatter::FORMAT_WIKI,
+ null,
+ '@^http://acme\.test$@' ),
+
+ //TODO: test HTML output
+ );
+ }
+
+ /**
+ * @dataProvider provideApiRequest
+ */
+ public function testApiRequest( DataValue $value, $dataType, $format,
$options, $pattern ) {
+ $params = array(
+ 'action' => 'wbformatvalue',
+ 'generate' => $format,
+ 'datatype' => $dataType,
+ 'datavalue' => json_encode( $value->toArray() ),
+ 'options' => $options === null ? null : json_encode(
$options ),
+ );
+
+ list( $resultArray, ) = $this->doApiRequest( $params );
+
+ $this->assertInternalType( 'array', $resultArray, 'top level
element must be an array' );
+ $this->assertArrayHasKey( 'result', $resultArray, 'top level
element must have a "result" key' );
+
+ $this->assertRegExp( $pattern, $resultArray['result'] );
+ }
+
+}
--
To view, visit https://gerrit.wikimedia.org/r/97510
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ide20888b8943b87c9900862a125decf1f01dde53
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Daniel Kinzler <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits