增加创建页面的标题有效性校验功能
parent
dcf17403b9
commit
c9e82dab06
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
namespace Isekai\Widgets\Api;
|
||||
|
||||
use MediaWiki\Api\ApiBase;
|
||||
use MediaWiki\Api\ApiMain;
|
||||
use MediaWiki\Api\ApiModuleManager;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use Wikimedia\ParamValidator\ParamValidator;
|
||||
use Isekai\Widgets\Api\IsekaiWidgets\ApiCreatePageValidateTitle;
|
||||
|
||||
class ApiIsekaiWidgets extends ApiBase {
|
||||
public static $methodModules = [
|
||||
'createpagevalidatetitle' => [
|
||||
'class' => ApiCreatePageValidateTitle::class,
|
||||
],
|
||||
];
|
||||
|
||||
private $mModuleMgr;
|
||||
private $mParams;
|
||||
/**
|
||||
* @param ApiMain $main
|
||||
* @param string $action
|
||||
*/
|
||||
public function __construct( ApiMain $main, $action )
|
||||
{
|
||||
parent::__construct($main, $action);
|
||||
|
||||
$this->mModuleMgr = new ApiModuleManager(
|
||||
$this,
|
||||
MediaWikiServices::getInstance()->getObjectFactory()
|
||||
);
|
||||
|
||||
// Allow custom modules to be added in LocalSettings.php
|
||||
$config = $this->getConfig();
|
||||
$this->mModuleMgr->addModules( self::$methodModules, 'method' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides to return this instance's module manager.
|
||||
* @return ApiModuleManager
|
||||
*/
|
||||
public function getModuleManager() {
|
||||
return $this->mModuleMgr;
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
$this->mParams = $this->extractRequestParams();
|
||||
|
||||
$modules = [];
|
||||
$this->instantiateModules( $modules, 'method' );
|
||||
$this->getResult()->addValue(null, 'modules', array_keys($modules));
|
||||
|
||||
foreach ( $modules as $module ) {
|
||||
$module->execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create instances of all modules requested by the client
|
||||
* @param array &$modules To append instantiated modules to
|
||||
* @param string $param Parameter name to read modules from
|
||||
*/
|
||||
private function instantiateModules( &$modules, $param ) {
|
||||
$wasPosted = $this->getRequest()->wasPosted();
|
||||
if ( isset( $this->mParams[$param] ) ) {
|
||||
foreach ( $this->mParams[$param] as $moduleName ) {
|
||||
$instance = $this->mModuleMgr->getModule( $moduleName, $param );
|
||||
if ( $instance === null ) {
|
||||
ApiBase::dieDebug( __METHOD__, 'Error instantiating module' );
|
||||
}
|
||||
if ( !$wasPosted && $instance->mustBePosted() ) {
|
||||
$this->dieWithErrorOrDebug( [ 'apierror-mustbeposted', $moduleName ] );
|
||||
}
|
||||
// Ignore duplicates. TODO 2.0: die()?
|
||||
if ( !array_key_exists( $moduleName, $modules ) ) {
|
||||
$modules[$moduleName] = $instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getAllowedParams( $flags = 0 ) {
|
||||
$result = [
|
||||
'method' => [
|
||||
ParamValidator::PARAM_ISMULTI => true,
|
||||
ParamValidator::PARAM_TYPE => 'submodule',
|
||||
],
|
||||
];
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function isInternal() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
namespace Isekai\Widgets\Api\IsekaiWidgets;
|
||||
|
||||
use Isekai\Widgets\Api\ApiIsekaiWidgets;
|
||||
use Isekai\Widgets\Utils\NewPageTitleValidationResult;
|
||||
use MediaWiki\Api\ApiBase;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Title\Title;
|
||||
use Wikimedia\ParamValidator\ParamValidator;
|
||||
|
||||
class ApiCreatePageValidateTitle extends ApiBase {
|
||||
/** @var MediaWikiServices */
|
||||
private $services;
|
||||
|
||||
/** @var ApiIsekaiWidgets */
|
||||
private $mParent;
|
||||
|
||||
public function __construct(ApiIsekaiWidgets $main, $method) {
|
||||
parent::__construct($main->getMain(), $method);
|
||||
|
||||
$this->mParent = $main;
|
||||
$this->services = MediaWikiServices::getInstance();
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
$newPageTitle = $this->getParameter('iwnewpagetitle');
|
||||
$newPageType = $this->getParameter('iwnewpagetype');
|
||||
|
||||
$config = $this->services->getMainConfig();
|
||||
$pageTypes = $config->get('IsekaiCreatePageTypes');
|
||||
|
||||
$newPageTypePrefix = "";
|
||||
foreach ($pageTypes as $item) {
|
||||
if ($item['id'] === $newPageType) {
|
||||
$newPageTypePrefix = $item['prefix'] ?? '';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$newPageTitle = $newPageTypePrefix . $newPageTitle;
|
||||
|
||||
$user = $this->getUser();
|
||||
$permissionManager = $this->services->getPermissionManager();
|
||||
|
||||
$result = $this->getResult();
|
||||
|
||||
$validationResult = new NewPageTitleValidationResult();
|
||||
|
||||
/*if ($permissionManager->userHasRight($user, 'editprotected')) {
|
||||
// 允许编辑受保护页面的用户,不进行标题检查
|
||||
$result->addValue(['isekaiwidget'], $this->getModuleName(), $validationResult->toArray());
|
||||
return true;
|
||||
}*/
|
||||
|
||||
// 检查页面是否已经存在
|
||||
try {
|
||||
$title = Title::newFromText($newPageTitle);
|
||||
if ($title && $title->exists()) {
|
||||
$validationResult->addError('pageexists', wfMessage('isekai-createpage-page-exists')->text());
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
wfLogWarning('Failed to validate new page title: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
// 调用Hook检查标题是否正确
|
||||
$hookContainer = $this->services->getHookContainer();
|
||||
$hookContainer->run('IsekaiWidgets::CreatePageValidateTitle', [
|
||||
$validationResult,
|
||||
$user,
|
||||
$newPageTitle,
|
||||
$newPageType,
|
||||
]);
|
||||
|
||||
$result->addValue(['isekaiwidget'], $this->getModuleName(), $validationResult->toArray());
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getAllowedParams($flags = 0) {
|
||||
return [
|
||||
'iwnewpagetitle' => [
|
||||
ParamValidator::PARAM_TYPE => 'string',
|
||||
ParamValidator::PARAM_DEFAULT => null,
|
||||
ParamValidator::PARAM_REQUIRED => true,
|
||||
],
|
||||
'iwnewpagetype' => [
|
||||
ParamValidator::PARAM_TYPE => 'string',
|
||||
ParamValidator::PARAM_DEFAULT => 'default',
|
||||
ParamValidator::PARAM_REQUIRED => false,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function getCacheMode($params) {
|
||||
return 'private';
|
||||
}
|
||||
|
||||
public function getParent() {
|
||||
return $this->mParent;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
namespace Isekai\Widgets\Utils;
|
||||
|
||||
class NewPageTitleValidationResult {
|
||||
private $hasError = false;
|
||||
private $hasWarning = false;
|
||||
|
||||
private $warnings = [];
|
||||
private $errors = [];
|
||||
|
||||
public function toArray(): array {
|
||||
return [
|
||||
'hasError' => $this->hasError ? 1 : 0,
|
||||
'hasWarning' => $this->hasWarning ? 1 : 0,
|
||||
'warnings' => $this->warnings,
|
||||
'errors' => $this->errors,
|
||||
];
|
||||
}
|
||||
|
||||
public function __serialize(): array {
|
||||
return $this->toArray();
|
||||
}
|
||||
|
||||
public function __unserialize(array $data): void {
|
||||
$this->hasError = (bool)$data['hasError'] ?? false;
|
||||
$this->hasWarning = (bool)$data['hasWarning'] ?? false;
|
||||
$this->warnings = $data['warnings'] ?? [];
|
||||
$this->errors = $data['errors'] ?? [];
|
||||
}
|
||||
|
||||
public function addError(string $errorCode, string $errorMessage): void {
|
||||
$this->hasError = true;
|
||||
$this->errors[] = [
|
||||
'code' => $errorCode,
|
||||
'message' => $errorMessage,
|
||||
];
|
||||
}
|
||||
|
||||
public function addWarning(string $warningCode, string $warningMessage): void {
|
||||
$this->hasWarning = true;
|
||||
$this->warnings[] = [
|
||||
'code' => $warningCode,
|
||||
'message' => $warningMessage,
|
||||
];
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue