| Current File : /home/jvzmxxx/wiki1/extensions/Wikibase/repo/includes/Api/FormatSnakValue.php |
<?php
namespace Wikibase\Repo\Api;
use ApiBase;
use ApiMain;
use DataValues\DataValue;
use DataValues\DataValueFactory;
use DataValues\IllegalValueException;
use DataValues\StringValue;
use InvalidArgumentException;
use LogicException;
use UsageException;
use ValueFormatters\FormatterOptions;
use ValueFormatters\ValueFormatter;
use Wikibase\DataModel\Entity\PropertyId;
use Wikibase\DataModel\Snak\PropertyValueSnak;
use Wikibase\Lib\OutputFormatValueFormatterFactory;
use Wikibase\Lib\OutputFormatSnakFormatterFactory;
use Wikibase\Lib\SnakFormatter;
use Wikibase\Lib\TypedValueFormatter;
use Wikibase\Repo\WikibaseRepo;
/**
* API module for using value formatters.
*
* @since 0.5
*
* @license GPL-2.0+
* @author Daniel Kinzler
* @author Addshore
* @author Marius Hoch
*/
class FormatSnakValue extends ApiBase {
/**
* @var OutputFormatValueFormatterFactory
*/
private $valueFormatterFactory;
/**
* @var OutputFormatSnakFormatterFactory
*/
private $snakFormatterFactory;
/**
* @var DataValueFactory
*/
private $dataValueFactory;
/**
* @var ApiErrorReporter
*/
private $errorReporter;
/**
* @param ApiMain $mainModule
* @param string $moduleName
* @param string $modulePrefix
*
* @see ApiBase::__construct
*/
public function __construct( ApiMain $mainModule, $moduleName, $modulePrefix = '' ) {
parent::__construct( $mainModule, $moduleName, $modulePrefix );
$wikibaseRepo = WikibaseRepo::getDefaultInstance();
$apiHelperFactory = $wikibaseRepo->getApiHelperFactory( $this->getContext() );
$this->setServices(
$wikibaseRepo->getValueFormatterFactory(),
$wikibaseRepo->getSnakFormatterFactory(),
$wikibaseRepo->getDataValueFactory(),
$apiHelperFactory->getErrorReporter( $this )
);
}
public function setServices(
OutputFormatValueFormatterFactory $valueFormatterFactory,
OutputFormatSnakFormatterFactory $snakFormatterFactory,
DataValueFactory $dataValueFactory,
ApiErrorReporter $apiErrorReporter
) {
$this->valueFormatterFactory = $valueFormatterFactory;
$this->snakFormatterFactory = $snakFormatterFactory;
$this->dataValueFactory = $dataValueFactory;
$this->errorReporter = $apiErrorReporter;
}
/**
* @see ApiBase::execute
*
* @since 0.1
*/
public function execute() {
$params = $this->extractRequestParams();
$this->requireMaxOneParameter( $params, 'property', 'datatype' );
$value = $this->decodeDataValue( $params['datavalue'] );
$dataTypeId = $this->getDataTypeId( $params );
$valueFormatter = $this->getValueFormatter();
$snak = null;
if ( isset( $params['property'] ) ) {
$snak = $this->decodeSnak( $params['property'], $value );
}
if ( $snak ) {
$snakFormatter = $this->getSnakFormatter();
$formattedValue = $snakFormatter->formatSnak( $snak );
} elseif ( $valueFormatter instanceof TypedValueFormatter ) {
// use data type id, if we can
$formattedValue = $valueFormatter->formatValue( $value, $dataTypeId );
} else {
// rely on value type
$formattedValue = $valueFormatter->format( $value );
}
$this->getResult()->addValue(
null,
'result',
$formattedValue
);
}
/**
* @throws LogicException
* @return ValueFormatter
*/
private function getValueFormatter() {
$params = $this->extractRequestParams();
$options = $this->getOptionsObject( $params['options'] );
$formatter = $this->valueFormatterFactory->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;
}
/**
* @throws LogicException
* @return SnakFormatter
*/
private function getSnakFormatter() {
$params = $this->extractRequestParams();
$options = $this->getOptionsObject( $params['options'] );
$formatter = $this->snakFormatterFactory->getSnakFormatter( $params['generate'], $options );
return $formatter;
}
/**
* @param string $propertyIdSerialization
* @param DataValue $dataValue
*
* @return PropertyValueSnak
*/
private function decodeSnak( $propertyIdSerialization, DataValue $dataValue ) {
try {
$propertyId = new PropertyId( $propertyIdSerialization );
} catch ( InvalidArgumentException $ex ) {
$this->errorReporter->dieException( $ex, 'badpropertyid' );
}
return new PropertyValueSnak( $propertyId, $dataValue );
}
/**
* @param string $json A JSON-encoded DataValue
*
* @throws UsageException
* @throws LogicException
* @return DataValue
*/
private function decodeDataValue( $json ) {
$data = json_decode( $json, true );
if ( !is_array( $data ) ) {
$this->errorReporter->dieError( 'Failed to decode datavalue', 'baddatavalue' );
}
try {
$value = $this->dataValueFactory->newFromArray( $data );
return $value;
} catch ( IllegalValueException $ex ) {
$this->errorReporter->dieException( $ex, 'baddatavalue' );
}
throw new LogicException( 'ApiErrorReporter::dieException did not throw a UsageException' );
}
/**
* @param string|null $optionsParam
*
* @return FormatterOptions
*/
private function getOptionsObject( $optionsParam ) {
$formatterOptions = new FormatterOptions();
$formatterOptions->setOption( ValueFormatter::OPT_LANG, $this->getLanguage()->getCode() );
if ( is_string( $optionsParam ) && $optionsParam !== '' ) {
$options = json_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
*/
private function getDataTypeId( array $params ) {
//TODO: could be looked up based on a property ID
return $params['datatype'];
}
/**
* @see ApiBase::getAllowedParams
*/
protected function getAllowedParams() {
return array(
'generate' => array(
self::PARAM_TYPE => array(
SnakFormatter::FORMAT_PLAIN,
SnakFormatter::FORMAT_WIKI,
SnakFormatter::FORMAT_HTML,
SnakFormatter::FORMAT_HTML_WIDGET,
),
self::PARAM_DFLT => SnakFormatter::FORMAT_WIKI,
self::PARAM_REQUIRED => false,
),
'datavalue' => array(
self::PARAM_TYPE => 'text',
self::PARAM_REQUIRED => true,
),
'datatype' => array(
self::PARAM_TYPE => WikibaseRepo::getDefaultInstance()->getDataTypeFactory()->getTypeIds(),
self::PARAM_REQUIRED => false,
),
'property' => array(
self::PARAM_TYPE => 'text',
self::PARAM_REQUIRED => false,
),
'options' => array(
self::PARAM_TYPE => 'text',
self::PARAM_REQUIRED => false,
),
);
}
/**
* @see ApiBase::getExamplesMessages
*/
protected function getExamplesMessages() {
$query = 'action=' . $this->getModuleName();
$hello = new StringValue( 'hello' );
$acme = new StringValue( 'http://acme.org' );
return array(
$query . '&' . wfArrayToCgi( array(
'datavalue' => json_encode( $hello->toArray() ),
) ) => 'apihelp-wbformatvalue-example-1',
$query . '&' . wfArrayToCgi( array(
'datavalue' => json_encode( $acme->toArray() ),
'datatype' => 'url',
'generate' => 'text/html',
) ) => 'apihelp-wbformatvalue-example-2',
//TODO: example for the options parameter, once we have something sensible to show there.
);
}
}