diff --git a/ChineseConvertor/ChineseConvertor.php b/ChineseConvertor/ChineseConvertor.php old mode 100644 new mode 100755 index 8695c1f..f383e7b --- a/ChineseConvertor/ChineseConvertor.php +++ b/ChineseConvertor/ChineseConvertor.php @@ -2,8 +2,6 @@ namespace LatinizeUrl; use Exception; -use MWHttpRequest; -use MediaWiki\Http\HttpRequestFactory; use Fukuball\Jieba\Jieba; use Fukuball\Jieba\Finalseg; use Fukuball\Jieba\Posseg; @@ -19,7 +17,11 @@ class ChineseConvertor extends BaseConvertor { public static function standalone(){ if(!self::$standalone){ - global $wgLatinizeUrlChineseConvertorConfig; + $service = MediaWikiServices::getInstance(); + + $config = $service->getMainConfig(); + $wgLatinizeUrlChineseConvertorConfig = $config->get('LatinizeUrlChineseConvertorConfig'); + self::$standalone = new self($wgLatinizeUrlChineseConvertorConfig); } return self::$standalone; diff --git a/JapaneseConvertor/JapaneseConvertor.php b/JapaneseConvertor/JapaneseConvertor.php old mode 100644 new mode 100755 index 144fa92..c43a57f --- a/JapaneseConvertor/JapaneseConvertor.php +++ b/JapaneseConvertor/JapaneseConvertor.php @@ -3,7 +3,6 @@ namespace LatinizeUrl; use Exception; -use MediaWiki\Http\HttpRequestFactory; use MediaWiki\MediaWikiServices; class JapaneseConvertor extends BaseConvertor { @@ -12,7 +11,11 @@ class JapaneseConvertor extends BaseConvertor { public static function standalone(){ if(!self::$standalone){ - global $wgLatinizeUrlJapaneseConvertorConfig; + $service = MediaWikiServices::getInstance(); + + $config = $service->getMainConfig(); + $wgLatinizeUrlJapaneseConvertorConfig = $config->get('LatinizeUrlJapaneseConvertorConfig'); + self::$standalone = new self($wgLatinizeUrlJapaneseConvertorConfig); } return self::$standalone; diff --git a/JapaneseConvertor/i18n/ja.json b/JapaneseConvertor/i18n/ja.json old mode 100644 new mode 100755 index d7e018f..e575c13 --- a/JapaneseConvertor/i18n/ja.json +++ b/JapaneseConvertor/i18n/ja.json @@ -1,3 +1,3 @@ { - "latinizeurl-japanese-convertor-desc": "LatinizeUrlの専用,漢字をローマ字に変換するためのツール。" + "latinizeurl-japanese-convertor-desc": "LatinizeUrlの専用,漢字と仮名をローマ字に変換するためのツール。" } \ No newline at end of file diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 8cc1732..01af565 --- a/README.md +++ b/README.md @@ -43,8 +43,7 @@ $LatinizeUrlChineseConvertorConfig['fallback'] = 'inner'; ``` 另:虚拟主机可以使用异世界百科的开放api ``` -https://static-www.isekai.cn:8082/api/toolkit/asciiurl/hanzi2pinyin -http://static-www.isekai.cn:8081/api/toolkit/asciiurl/hanzi2pinyin +https://www.isekai.cn/api/toolkit/asciiurl/hanzi2pinyin ``` 不保证稳定性,建议自建daemon diff --git a/bin/updatePinyinUrl.php b/bin/updatePinyinUrl.php old mode 100644 new mode 100755 index 7d0c80c..4334e28 --- a/bin/updatePinyinUrl.php +++ b/bin/updatePinyinUrl.php @@ -1,11 +1,12 @@ getMainConfig(); + $latinizeUrlConf = $config->get('LatinizeUrlConfig'); $force = $this->hasOption( 'force' ); $outputFileName = $this->getArg( 0 ); @@ -35,12 +39,12 @@ class UpdateLatinizeUrl extends Maintenance { $outputFile = fopen($outputFileName, 'w'); } - $dbw = $this->getDB( DB_MASTER ); + $dbw = $this->getDB( DB_PRIMARY ); if ( $dbw->getType() !== 'mysql' ) { $this->fatalError( "This change is only needed on MySQL, quitting.\n" ); } - $convertor = new ChineseConvertor($wgLatinizeUrlConfig); + $convertor = new ChineseConvertor($latinizeUrlConf); $res = $this->findRows( $dbw ); foreach($res as $one){ @@ -65,11 +69,16 @@ class UpdateLatinizeUrl extends Maintenance { } public function searchIndexUpdateCallback( $dbw, $row ) { - return $this->updateSearchIndexForPage( $dbw, $row->si_page ); + // return $this->updateSearchIndexForPage( $dbw, $row->si_page ); } - private function getFullUrl($pageName){ - global $wgServer, $wgArticlePath, $wgUsePathInfo; + private function getFullUrl($pageName) { + $service = MediaWikiServices::getInstance(); + + $config = $service->getMainConfig(); + $wgServer = $config->get('Server'); + $wgArticlePath = $config->get('ArticlePath'); + $wgUsePathInfo = $config->get('UsePathInfo'); $pageName = implode("/", array_map("urlencode", explode("/", $pageName))); if($wgUsePathInfo){ return $wgServer . str_replace('$1', $pageName, $wgArticlePath); diff --git a/composer.json b/composer.json old mode 100644 new mode 100755 index c32c348..d23f547 --- a/composer.json +++ b/composer.json @@ -1,9 +1,9 @@ { - "name": "chs/pinyin-url", + "name": "hyperzlib/pinyin-url", "type": "project", "authors": [ { - "name": "无名写手", + "name": "hyperzlib", "email": "hyperzlib@outlook.com" } ], diff --git a/extension.json b/extension.json old mode 100644 new mode 100755 index ec1d575..293349c --- a/extension.json +++ b/extension.json @@ -1,11 +1,14 @@ { "name": "LatinizeUrl", - "author": "hyperzlib", + "author": "Hyperzlib", "url": "https://github.com/Isekai-Project/mediawiki-extension-LatinizeUrl", "descriptionmsg": "latinizeurl-desc", "version": "1.0.4", "license-name": "MIT", "type": "other", + "requires": { + "MediaWiki": ">= 1.39.0" + }, "ExtensionMessagesFiles": { "LatinizeUrlAlias": "LatinizeUrl.alias.php" }, @@ -29,8 +32,8 @@ "Collation::factory": [ "LatinizeUrl\\Hooks::onCollationFactory" ], - "SkinTemplateOutputPageBeforeExec": [ - "LatinizeUrl\\Hooks::onSkinTemplateOutputPageBeforeExec" + "SkinTemplateNavigation::Universal": [ + "LatinizeUrl\\Hooks::addToolboxLink" ], "BeforePageDisplay": [ "LatinizeUrl\\Hooks::onBeforePageDisplay" @@ -38,14 +41,14 @@ "InitializeParseTitle": [ "LatinizeUrl\\Hooks::onInitializeParseTitle" ], - "ArticleDeleteComplete": [ - "LatinizeUrl\\Hooks::onArticleDeleteComplete" + "PageDeleteComplete": [ + "LatinizeUrl\\Hooks::onPageDeleteComplete" ], - "PageContentInsertComplete": [ - "LatinizeUrl\\Hooks::onPageContentInsertComplete" + "PageSaveComplete": [ + "LatinizeUrl\\Hooks::onPageSaveComplete" ], - "TitleMoveComplete": [ - "LatinizeUrl\\Hooks::onTitleMoveComplete" + "PageMoveComplete": [ + "LatinizeUrl\\Hooks::onPageMoveComplete" ], "GetLocalURL": [ "LatinizeUrl\\Hooks::onGetArticleUrl" @@ -67,7 +70,12 @@ "remoteExtPath": "LatinizeUrl" }, "config": { - "LatinizeUrlForceRedirect": true + "LatinizeUrlConfig": { + "value": {} + }, + "LatinizeUrlForceRedirect": { + "value": true + } }, - "manifest_version": 1 + "manifest_version": 2 } diff --git a/i18n/en.json b/i18n/en.json old mode 100644 new mode 100755 index 2ddf8f8..3bce800 --- a/i18n/en.json +++ b/i18n/en.json @@ -1,5 +1,5 @@ { - "latinizeurl-desc": "Latinize none-ASCII chars in url.", + "latinizeurl-desc": "Convert none-ASCII chars to ASCII chars in url.", "latinizeurl-customurl": "Custom URL", "customurl-legend": "Custom URL", "customurl-url-field-label": "The URL you want to use:", diff --git a/i18n/ja.json b/i18n/ja.json old mode 100644 new mode 100755 index 26b1ada..6833b02 --- a/i18n/ja.json +++ b/i18n/ja.json @@ -1,10 +1,10 @@ { - "latinizeurl-desc": "漢字をローマ字に変換する", + "latinizeurl-desc": "URLの漢字と仮名をローマ字に変換する", "latinizeurl-customurl": "URLの編集", "customurl-legend": "URLの編集", "customurl-url-field-label": "使用したいURL:", - "customurl-url-field-help": "ASCII文字をお勧めします。入力しない場合は、漢字に対応するローマ字が自動的に生成されます。", + "customurl-url-field-help": "ASCII文字をお勧めします。入力しない場合は、漢字と仮名に対応するローマ字が自動的に変換されます。", "rename-subpage-checkbox-label": "下位ページのURLを一緒に変更する", - "customurl-set-success": "このページの新しいURLは [[$1|$2]].", + "customurl-set-success": "このページの新しいURLは [[$1|$2]] です.", "customurl-set-failed": "このURLは無効です。" } \ No newline at end of file diff --git a/i18n/zh-hans.json b/i18n/zh-hans.json old mode 100644 new mode 100755 index ede531e..3080e96 --- a/i18n/zh-hans.json +++ b/i18n/zh-hans.json @@ -1,5 +1,5 @@ { - "latinizeurl-desc": "把url中的汉字转换成拼音。", + "latinizeurl-desc": "将URL中的汉字转换成拼音。", "latinizeurl-customurl": "自定义URL", "customurl-legend": "自定义URL", "customurl-url-field-label": "你想要设置的URL:", diff --git a/includes/Hooks.php b/includes/Hooks.php old mode 100644 new mode 100755 index 26769de..2cf2361 --- a/includes/Hooks.php +++ b/includes/Hooks.php @@ -1,13 +1,14 @@ getMainConfig(); + $wgLatinizeUrlForceRedirect = $config->get('LatinizeUrlForceRedirect'); if(in_array($title->getNamespace(), self::$allowedNS)){ $realTitle = Utils::getTitleBySlugUrl($title, $title->getNamespace()); @@ -59,43 +63,54 @@ class Hooks { try { if(in_array($title->getNamespace(), self::$allowedNS) && Utils::titleSlugExists($title)){ $slug = Title::newFromText(Utils::getSlugUrlByTitle($title), $title->getNamespace()); - $slugEncoded = Utils::encodeUriComponent($slug->getPrefixedText()); - $titleEncoded = Utils::encodeUriComponent($title->getPrefixedText()); - $url = str_replace($titleEncoded, $slugEncoded, $url); + if ($slug) { + $slugEncoded = Utils::encodeUriComponent($slug->getPrefixedText()); + $titleEncoded = Utils::encodeUriComponent($title->getPrefixedText()); + $url = str_replace($titleEncoded, $slugEncoded, $url); + } } } catch(DBQueryError $ex){ } } - public static function onArticleDeleteComplete(&$article, User &$user, $reason, $id, \Content $content = null, \LogEntry $logEntry){ - if(in_array($article->getTitle()->getNamespace(), self::$allowedNS)){ - Utils::removeTitleSlugMap($article->getTitle()->getText()); + public static function onPageDeleteComplete(ProperPageIdentity $page, Authority $deleter, $reason, $pageID, $deletedRev, $logEntry, $archivedRevisionCount) { + $title = TitleValue::newFromPage( $page ); + if(in_array($title->getNamespace(), self::$allowedNS)){ //不是普通页面就跳过 + Utils::removeTitleSlugMap($title->getText()); } } - public static function onPageContentInsertComplete(\WikiPage &$wikiPage, User &$user, $content, $summary, $isMinor, $isWatch, $section, &$flags, $revision){ + + /** + * @param \WikiPage $wikiPage + * @param \MediaWiki\User\UserIdentity $user + * @param string $summary + * @param int $flags + * @param \MediaWiki\Revision\RevisionRecord $revisionRecord + * @param \MediaWiki\Storage\EditResult $editResult + */ + public static function onPageSaveComplete(&$wikiPage, $user, $summary, $flags, $revisionRecord, $editResult){ if(!in_array($wikiPage->getTitle()->getNamespace(), self::$allowedNS)){ //不是普通页面就跳过 return; } - try { + if ($flags & EDIT_NEW) { $title = $wikiPage->getTitle(); $parsedData = Utils::parseTitleToAscii($title, $title->getPageLanguage()); Utils::addTitleSlugMap($title->getText(), $parsedData['slug'], $parsedData['latinize']); - } catch (\Exception $e) { - } } - public static function onTitleMoveComplete(Title &$title, Title &$newTitle, User $user, $oldid, $newid, $reason, $revision){ - if(!in_array($newTitle->getNamespace(), self::$allowedNS)){ //不是普通页面就跳过 + public static function onPageMoveComplete(LinkTarget $old, LinkTarget $new, UserIdentity $userIdentity, $pageid, $redirid, $reason, $revision) { + if (!in_array($new->getNamespace(), self::$allowedNS)) { //不是普通页面就跳过 return; } + $title = MediaWikiServices::getInstance()->getTitleFactory()->newFromLinkTarget($new); try { - $parsedData = Utils::parseTitleToAscii($newTitle, $newTitle->getPageLanguage()); - Utils::addTitleSlugMap($newTitle->getText(), $parsedData['slug'], $parsedData['latinize']); + $parsedData = Utils::parseTitleToAscii($title, $title->getPageLanguage()); + Utils::addTitleSlugMap($title->getText(), $parsedData['slug'], $parsedData['latinize']); } catch (\Exception $e) { } @@ -117,14 +132,14 @@ class Hooks { } } - public static function onSkinTemplateOutputPageBeforeExec(\Skin $skin, \QuickTemplate $template){ + public static function addToolboxLink(\Skin $skin, array &$links){ $service = MediaWikiServices::getInstance(); $user = $skin->getContext()->getUser(); $title = $skin->getRelevantTitle(); if(in_array($title->getNamespace(), self::$allowedNS)){ if($service->getPermissionManager()->userHasRight($user, 'delete') || Utils::hasUserEditedPage($title, $user)){ - $template->data['content_navigation']['page-secondary']['custom-url'] = [ + $links['page-secondary']['custom-url'] = [ 'class' => false, 'text' => wfMessage('latinizeurl-customurl')->text(), 'href' => \SpecialPage::getTitleFor('CustomUrl', $title->getPrefixedDBKey())->getLocalURL(), diff --git a/includes/LatinizeCollation.php b/includes/LatinizeCollation.php old mode 100644 new mode 100755 index 7ed39e4..4933da8 --- a/includes/LatinizeCollation.php +++ b/includes/LatinizeCollation.php @@ -5,7 +5,7 @@ use Collation; use MediaWiki\MediaWikiServices; class LatinizeCollation extends Collation { - private $cache = null; + private $cache; public function __construct(){ $this->cache = MediaWikiServices::getInstance()->getMainWANObjectCache(); @@ -18,8 +18,7 @@ class LatinizeCollation extends Collation { function() use($string){ $convertor = Utils::getConvertor(); $latinize = $convertor->parse($string); - $slug = Utils::wordListToUrl($latinize); - return $slug; + return Utils::wordListToUrl($latinize); } ); } diff --git a/includes/Patcher.php b/includes/Patcher.php old mode 100644 new mode 100755 index a9e0ba9..2fb2b94 --- a/includes/Patcher.php +++ b/includes/Patcher.php @@ -15,7 +15,7 @@ class Patcher { } public function findPatchVersion($name){ - $regex = '/\/\/ Start ' . $this->tag . ' ([0-9\.\-]+) ' . $name . ' Patch\n.*?\/\/ End ' . $this->tag . ' [0-9\.\-]+ ' . $name . ' Patch/is'; + $regex = '/\/\/ Start ' . $this->tag . ' ([0-9.\-]+) ' . $name . ' Patch\n.*?\/\/ End ' . $this->tag . ' [0-9.\-]+ ' . $name . ' Patch/is'; if(preg_match($regex, $this->content, $matches, PREG_OFFSET_CAPTURE)){ $ret = []; $ret['start'] = $matches[0][1]; @@ -32,7 +32,7 @@ class Patcher { $patchContent = ['MediaWikiServices::getInstance()->getHookContainer()->run( \'InitializeParseTitle\', [ &$ret, $request ] );']; $patchFinalContent = $this->makePatchContent($patchName, $patchContent, 2); $currentPatch = $this->findPatchVersion($patchName); - if($currentPatch){ + if ($currentPatch) { if($currentPatch['version'] != $this->version){ //需要更新 $this->content = substr($this->content, 0, $currentPatch['start'] - 2) . $patchFinalContent @@ -53,7 +53,7 @@ class Patcher { if(!is_array($content)) $content = explode("\n", $content); $lines = array_merge([ '// Start ' . $this->tag . ' ' . $this->version . ' ' . $name . ' Patch', - '// This code is added by ' . $this->tag . ', Donnot remove this code untill you uninstall ' . $this->tag . '.', + '// This code is added by ' . $this->tag . ' extension, Do not remove this code until you uninstall ' . $this->tag . ' extension.', ], $content, [ '// End ' . $this->tag . ' ' . $this->version . ' ' . $name . ' Patch', ]); diff --git a/includes/Utils.php b/includes/Utils.php old mode 100644 new mode 100755 index d082bb5..0dcc89d --- a/includes/Utils.php +++ b/includes/Utils.php @@ -7,7 +7,9 @@ use ExtensionRegistry; use Title; use User; use Language; +use MediaWiki\Extension\AbuseFilter\Consequences\Consequence\Tag; use MediaWiki\MediaWikiServices; +use StubUserLang; class Utils { private static $dbr = null; @@ -16,13 +18,15 @@ class Utils { public static function initMasterDb(){ if(!self::$dbw){ - self::$dbw = wfGetDB(DB_MASTER); + self::$dbw = MediaWikiServices::getInstance()->getDBLoadBalancer() + ->getMaintenanceConnectionRef(DB_PRIMARY); } } public static function initReplicaDb(){ if(!self::$dbr){ - self::$dbr = wfGetDB(DB_REPLICA); + self::$dbr = MediaWikiServices::getInstance()->getDBLoadBalancer() + ->getMaintenanceConnectionRef(DB_REPLICA); } } @@ -329,22 +333,22 @@ class Utils { return false; } - public static function encodeUriComponent($str){ + public static function encodeUriComponent($str) { $entities = ['+', '%21', '%2A', '%27', '%28', '%29', '%3B', '%3A', '%40', '%26', '%3D', '%2B', '%24', '%2C', '%2F', '%3F', '%25', '%23', '%5B', '%5D']; $replacements = ['_', '!', '*', "'", "(", ")", ";", ":", "@", "&", "=", "+", "$", ",", "/", "?", "%", "#", "[", "]"]; return str_replace($entities, $replacements, implode("/", array_map("urlencode", explode("/", $str)))); } /** - * @param Language|string|null $language - 语言 + * @param Language|StubUserLang|string|null $language - 语言 * @return BaseConvertor 转换器 */ - public static function getConvertor($language = null){ - if($language == null){ + public static function getConvertor($language = null) { + if ($language == null) { $language = MediaWikiServices::getInstance()->getContentLanguage(); } - if($language instanceof Language){ + if (is_callable([$language, 'getCode'])) { $language = $language->getCode(); } @@ -360,7 +364,7 @@ class Utils { /** * @param Title $title - 要转换的标题 - * @param Language|string|null $language - 语言 + * @param Language|StubUserLang|string|null $language - 语言 * @return mixed 转换器 */ public static function parseTitleToAscii(Title $title, Language $language){ diff --git a/specials/SpecialCustomUrl.php b/specials/SpecialCustomUrl.php old mode 100644 new mode 100755 index d6b528b..75499dc --- a/specials/SpecialCustomUrl.php +++ b/specials/SpecialCustomUrl.php @@ -1,70 +1,184 @@ nsInfo = $service->getNamespaceInfo(); + $this->linkBatchFactory = $service->getLinkBatchFactory(); } - public function doesWrites() - { + public function doesWrites() { return true; } - public function execute($par) - { - parent::execute($par); + public function execute($par) { + $this->useTransactionalTimeLimit(); - $this->getSkin()->setRelevantTitle($this->title); - $out = $this->getOutput(); - $out->setPageTitle($this->msg('latinizeurl-customurl', $this->title->getPrefixedText())); - } + $this->checkReadOnly(); + + $this->setHeaders(); + $this->outputHeader(); - protected function setParameter( $par ) { $service = MediaWikiServices::getInstance(); - $title = \Title::newFromText( $par ); + $request = $this->getRequest(); + + $this->target = $par ?? $request->getText('target'); + $title = \Title::newFromText($this->target); $this->title = $title; + $this->getSkin()->setRelevantTitle($this->title); - if ( !$title ) { + $user = $this->getUser(); + + if (!$title) { throw new \ErrorPageError( 'notargettitle', 'notargettext' ); + return; } - if ( !$title->exists() ) { + if (!$title->exists()) { throw new \ErrorPageError( 'nopagetitle', 'nopagetext' ); } - - - $isAdmin = $service->getPermissionManager()->userHasRight($this->getUser(), 'delete'); + + $isAdmin = $service->getPermissionManager()->userHasRight($this->getUser(), 'move'); $this->isAdmin = $isAdmin; $userEditedPage = Utils::hasUserEditedPage($this->title, $this->getUser()); $this->userEditedPage = $userEditedPage; - - $this->slug = $this->getCurrentSlug(); - if(!$this->hasAccess()){ + if (!$this->hasAccess()){ throw new \PermissionsError('move'); } + + $this->slug = $this->getCurrentSlug(); + + if ($request->getRawVal('action') == 'submit' && $request->wasPosted() && $user->matchEditToken($request->getVal('wpEditToken'))) { + $this->doSubmit(); + } else { + $this->showForm( [] ); + } } protected function hasAccess(){ return $this->isAdmin || $this->userEditedPage; } - protected function showForm($err, $isPermErr){ + protected function showForm($err, $isPermError = false){ + $user = $this->getUser(); + $out = $this->getOutput(); + $out->setPageTitle($this->msg('latinizeurl-customurl')); + $out->addModuleStyles([ + 'mediawiki.special', + 'mediawiki.interface.helpers.styles' + ]); + $out->addModules('mediawiki.misc-authed-ooui'); + + $out->enableOOUI(); + + $fields = []; + + $fields[] = new \OOUI\FieldLayout( + new \OOUI\TextInputWidget([ + 'name' => 'wpSlug', + 'id' => 'wpSlug', + 'value' => $this->getCurrentSlug(), + ]), + [ + 'label' => $this->msg('customurl-url-field-label')->text(), + 'help' => $this->msg('customurl-url-field-help')->text(), + 'align' => 'top', + ] + ); + + if ($this->title->hasSubpages()) { + $fields[] = new \OOUI\FieldLayout( + new \OOUI\CheckboxInputWidget([ + 'name' => 'wpRenameSubpage', + 'id' => 'wpRenameSubpage', + 'value' => '1', + ]), + [ + 'label' => $this->msg('rename-subpage-checkbox-label')->text(), + 'align' => 'inline', + ] + ); + } + $fields[] = new \OOUI\FieldLayout( + new \OOUI\ButtonInputWidget( [ + 'name' => 'wpConfirm', + 'value' => $this->msg('htmlform-submit')->text(), + 'label' => $this->msg('htmlform-submit')->text(), + 'flags' => ['primary', 'progressive'], + 'type' => 'submit', + ]), + [ + 'align' => 'top', + ] + ); + + $fieldset = new \OOUI\FieldsetLayout( [ + 'label' => $this->msg('customurl-legend')->text(), + 'id' => 'mw-customurl-table', + 'items' => $fields, + ] ); + + $form = new \OOUI\FormLayout([ + 'method' => 'post', + 'action' => $this->getPageTitle($this->target)->getLocalURL('action=submit'), + 'id' => 'customurl', + ]); + + $form->appendContent( + $fieldset, + new \OOUI\HtmlSnippet( + Html::hidden('wpEditToken', $user->getEditToken()) + ) + ); + + $out->addHTML( + new \OOUI\PanelLayout([ + 'classes' => ['movepage-wrapper', 'customurl-wrapper'], + 'expanded' => false, + 'padded' => true, + 'framed' => true, + 'content' => $form, + ]) + ); + + if ($this->title->hasSubpages()) { + $this->showSubpages($this->title); + } } private function getCurrentSlug(){ @@ -75,33 +189,22 @@ class SpecialCustomUrl extends FormSpecialPage return $this->title->getText(); } } + + public function doSubmit() { + $user = $this->getUser(); - protected function getFormFields() { - $fields = []; - - $fields['slug'] = [ - 'type' => 'text', - 'label-message' => 'customurl-url-field-label', - 'help-message' => 'customurl-url-field-help', - 'default' => $this->getCurrentSlug(), - ]; - - if($this->title->hasSubpages()){ - $fields['rename-subpage'] = [ - 'type' => 'check', - 'label-message' => 'rename-subpage-checkbox-label', - 'default' => false, - ]; - } + if ($user->pingLimiter('customurl')) { + throw new ThrottledError; + } + + $request = $this->getRequest(); + $slug = $request->getText('wpSlug'); + $renameSubpages = $request->getBool('wpRenameSubpage'); - return $fields; - } - - public function onSubmit(array $data, \HTMLForm $form = null ) { $originSlug = Utils::getSlugByTitle($this->title); - $slug = $data['slug']; + $latinize = []; - if(empty($slug)){ //自动生成 + if (empty($slug)) { //自动生成 $parsedData = Utils::parseTitleToAscii($this->title, $this->title->getPageLanguage()); $slug = $parsedData['slug']; $latinize = $parsedData['latinize']; @@ -118,7 +221,7 @@ class SpecialCustomUrl extends FormSpecialPage $realSlug = Utils::addTitleSlugMap($this->title->getText(), $slug, $latinize, $custom); } - if(isset($data['rename-subpage']) && $data['rename-subpage']){ + if($renameSubpages){ //更新子页面的slug $subpages = $this->title->getSubpages(); $originSlugLen = strlen($originSlug); @@ -132,11 +235,76 @@ class SpecialCustomUrl extends FormSpecialPage } } $this->slug = $realSlug; + + $this->onSuccess(); return true; } + + /** + * Show subpages of the page being moved. Section is not shown if both current + * namespace does not support subpages and no talk subpages were found. + * + * @param Title $title Page being moved. + */ + private function showSubpages( $title ) { + $nsHasSubpages = $this->nsInfo->hasSubpages( $title->getNamespace() ); + $subpages = $title->getSubpages(); + $count = $subpages instanceof \TitleArray ? $subpages->count() : 0; + + $titleIsTalk = $title->isTalkPage(); + $subpagesTalk = $title->getTalkPage()->getSubpages(); + $countTalk = $subpagesTalk instanceof \TitleArray ? $subpagesTalk->count() : 0; + $totalCount = $count + $countTalk; + + if ( !$nsHasSubpages && $countTalk == 0 ) { + return; + } + + $this->getOutput()->wrapWikiMsg( + '== $1 ==', + [ 'movesubpage', ( $titleIsTalk ? $count : $totalCount ) ] + ); + + if ( $nsHasSubpages ) { + $this->showSubpagesList( $subpages, $count, 'movesubpagetext', true ); + } + + if ( !$titleIsTalk && $countTalk > 0 ) { + $this->showSubpagesList( $subpagesTalk, $countTalk, 'movesubpagetalktext' ); + } + } + + private function showSubpagesList( $subpages, $pagecount, $wikiMsg, $noSubpageMsg = false ) { + $out = $this->getOutput(); + + # No subpages. + if ( $pagecount == 0 && $noSubpageMsg ) { + $out->addWikiMsg( 'movenosubpage' ); + return; + } + + $out->addWikiMsg( $wikiMsg, $this->getLanguage()->formatNum( $pagecount ) ); + $out->addHTML( "