jenkins-bot has submitted this change and it was merged.

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, 358 insertions(+), 0 deletions(-)

Approvals:
  Tobias Gritschacher: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/repo/Wikibase.classes.php b/repo/Wikibase.classes.php
index 9e347fc..408dcb2 100644
--- a/repo/Wikibase.classes.php
+++ b/repo/Wikibase.classes.php
@@ -112,6 +112,7 @@
                'Wikibase\Api\ClaimModificationHelper' => 
'includes/api/ClaimModificationHelper.php',
                'Wikibase\Api\ResultBuilder' => 
'includes/api/ResultBuilder.php',
                'Wikibase\Api\SiteLinkTargetProvider' => 
'includes/api/SiteLinkTargetProvider.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..0610f99
--- /dev/null
+++ b/repo/includes/api/FormatSnakValue.php
@@ -0,0 +1,251 @@
+<?php
+
+namespace Wikibase\Api;
+
+use ApiBase;
+use DataValues\DataValue;
+use DataValues\DataValueFactory;
+use DataValues\IllegalValueException;
+use DataValues\StringValue;
+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() {
+               $query = "api.php?action=" . $this->getModuleName() ;
+               $hello = new StringValue( 'hello' );
+               $acme = new StringValue( 'http://acme.org' );
+
+               return array(
+                       $query . '&' . wfArrayToCgi( array(
+                               'datavalue' => json_encode( $hello->toArray() ),
+                       ) ) => 'Format a simple string value.',
+
+                       $query . '&' . wfArrayToCgi( array(
+                               'datavalue' => json_encode( $acme->toArray() ),
+                               'datatype' => 'url',
+                               'generate' => 'text/html',
+                       ) ) => 'Format a string value as a URL in HTML.',
+
+                       //TODO: example for the options parameter, once we have 
something sensible to show there.
+               );
+       }
+}
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&#58;//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: merged
Gerrit-Change-Id: Ide20888b8943b87c9900862a125decf1f01dde53
Gerrit-PatchSet: 3
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Daniel Kinzler <[email protected]>
Gerrit-Reviewer: Addshore <[email protected]>
Gerrit-Reviewer: Aude <[email protected]>
Gerrit-Reviewer: Daniel Kinzler <[email protected]>
Gerrit-Reviewer: Daniel Werner <[email protected]>
Gerrit-Reviewer: Henning Snater <[email protected]>
Gerrit-Reviewer: Jeroen De Dauw <[email protected]>
Gerrit-Reviewer: Tobias Gritschacher <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to