This brings significant modularization to the Action API's parameter validation, and allows the Action API and MW REST API to share validation code. Note there are several changes in this patch that may affect other code; see the entries in RELEASE-NOTES-1.35 for details. Bug: T142080 Bug: T232672 Bug: T21195 Bug: T34675 Bug: T154774 Change-Id: I1462edc1701278760fa695308007006868b249fc Depends-On: I10011be060fe6d27c7527312ad41218786b3f40d
136 lines
3.5 KiB
PHP
136 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace MediaWiki\Api\Validator;
|
|
|
|
use ApiMain;
|
|
use MediaWiki\Message\Converter as MessageConverter;
|
|
use Wikimedia\Message\DataMessageValue;
|
|
use Wikimedia\ParamValidator\Callbacks;
|
|
use Wikimedia\ParamValidator\Util\UploadedFile;
|
|
|
|
/**
|
|
* ParamValidator callbacks for the Action API
|
|
* @since 1.35
|
|
* @ingroup API
|
|
*/
|
|
class ApiParamValidatorCallbacks implements Callbacks {
|
|
|
|
/** @var ApiMain */
|
|
private $apiMain;
|
|
|
|
/** @var MessageConverter */
|
|
private $messageConverter;
|
|
|
|
/**
|
|
* @internal
|
|
* @param ApiMain $main
|
|
*/
|
|
public function __construct( ApiMain $main ) {
|
|
$this->apiMain = $main;
|
|
$this->messageConverter = new MessageConverter();
|
|
}
|
|
|
|
public function hasParam( $name, array $options ) {
|
|
return $this->apiMain->getCheck( $name );
|
|
}
|
|
|
|
public function getValue( $name, $default, array $options ) {
|
|
$value = $this->apiMain->getVal( $name, $default );
|
|
$request = $this->apiMain->getRequest();
|
|
$rawValue = $request->getRawVal( $name );
|
|
|
|
if ( is_string( $rawValue ) ) {
|
|
// Preserve U+001F for multi-values
|
|
if ( substr( $rawValue, 0, 1 ) === "\x1f" ) {
|
|
// This loses the potential checkTitleEncoding() transformation done by
|
|
// WebRequest for $_GET. Let's call that a feature.
|
|
$value = implode( "\x1f", $request->normalizeUnicode( explode( "\x1f", $rawValue ) ) );
|
|
}
|
|
|
|
// Check for NFC normalization, and warn
|
|
if ( $rawValue !== $value ) {
|
|
$options['module']->handleParamNormalization( $name, $value, $rawValue );
|
|
}
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
public function hasUpload( $name, array $options ) {
|
|
return $this->getUploadedFile( $name, $options ) !== null;
|
|
}
|
|
|
|
public function getUploadedFile( $name, array $options ) {
|
|
$upload = $this->apiMain->getUpload( $name );
|
|
if ( !$upload->exists() ) {
|
|
return null;
|
|
}
|
|
return new UploadedFile( [
|
|
'error' => $upload->getError(),
|
|
'tmp_name' => $upload->getTempName(),
|
|
'size' => $upload->getSize(),
|
|
'name' => $upload->getName(),
|
|
'type' => $upload->getType(),
|
|
] );
|
|
}
|
|
|
|
public function recordCondition(
|
|
DataMessageValue $message, $name, $value, array $settings, array $options
|
|
) {
|
|
$module = $options['module'];
|
|
|
|
$code = $message->getCode();
|
|
switch ( $code ) {
|
|
case 'param-deprecated': // @codeCoverageIgnore
|
|
case 'deprecated-value': // @codeCoverageIgnore
|
|
if ( $code === 'param-deprecated' ) {
|
|
$feature = $name;
|
|
} else {
|
|
$feature = $name . '=' . $value;
|
|
$data = $message->getData() ?? [];
|
|
if ( isset( $data['💩'] ) ) {
|
|
// This is from an old-style Message. Strip out ParamValidator's added params.
|
|
unset( $data['💩'] );
|
|
$message = DataMessageValue::new(
|
|
$message->getKey(),
|
|
array_slice( $message->getParams(), 2 ),
|
|
$code,
|
|
$data
|
|
);
|
|
}
|
|
}
|
|
|
|
$m = $module;
|
|
while ( !$m->isMain() ) {
|
|
$p = $m->getParent();
|
|
$mName = $m->getModuleName();
|
|
$mParam = $p->encodeParamName( $p->getModuleManager()->getModuleGroup( $mName ) );
|
|
$feature = "{$mParam}={$mName}&{$feature}";
|
|
$m = $p;
|
|
}
|
|
$module->addDeprecation(
|
|
$this->messageConverter->convertMessageValue( $message ),
|
|
$feature,
|
|
$message->getData()
|
|
);
|
|
break;
|
|
|
|
case 'param-sensitive': // @codeCoverageIgnore
|
|
$module->getMain()->markParamsSensitive( $name );
|
|
break;
|
|
|
|
default:
|
|
$module->addWarning(
|
|
$this->messageConverter->convertMessageValue( $message ),
|
|
$message->getCode(),
|
|
$message->getData()
|
|
);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public function useHighLimits( array $options ) {
|
|
return $this->apiMain->canApiHighLimits();
|
|
}
|
|
|
|
}
|